代码之家  ›  专栏  ›  技术社区  ›  Homde

通过IList后门生成通用列表

  •  8
  • Homde  · 技术社区  · 15 年前

    我有一个场景,一个类加载一种类型的对象,由于抽象的原因,我不能使用一个泛型类(泛型会像癌症一样扩散:),但我经常想在检索到对象后使用一个泛型版本,这导致了这样的代码(简化):

    List<SomeClass> items = Storage.LoadItems(filename).OfType<SomeClass>().ToList();
    

    当LoadItems返回List<object>时,我意识到,为什么不

    public void LoadItems(string filename,IList list);
    

    现在我可以做这个了

    List<SomeClass> items = new  List<SomeClass>();
    LoadItems(filename,items);
    

    我也有点好奇,你能做到这一点,如果你试图添加一个错误类型的对象,你会得到一个异常,但这是否意味着通用列表也会进行类型检查?(这似乎有点不必要)

    编辑 实际上,将模式修改为

    public IList LoadItems(string filename,IList list=null);
    

    这样,您就可以流畅地使用该语句,如果没有传递列表,您只需实例化一个列表<object>

    4 回复  |  直到 15 年前
        1
  •  3
  •   SLaks    15 年前

    List<T> 工具 IList 明确地。 实现强制转换为 T 并调用常规(泛型)方法。

    伊利斯特 例如:

    void System.Collections.IList.Insert(int index, Object item) 
    {
        ThrowHelper.IfNullAndNullsAreIllegalThenThrow<T>(item, ExceptionArgument.item); 
    
        try {
            Insert(index, (T) item); 
        }
        catch (InvalidCastException) {
            ThrowHelper.ThrowWrongValueTypeArgumentException(item, typeof(T));
        } 
    }
    

    它不使用 as T型
    你只能写信 as T where T : class .

        2
  •  1
  •   Marc Gravell    15 年前

    使用 IList 当然 dynamic 为了达到同样的目的。

    是的,它将添加一个类型检查(通过cast/unbox),但这并不繁重。如果 T struct 然后你也有一些拳击/击球,但这也不像人们担心的那么糟糕。

    在这种情况下, 我不会有事的。

        3
  •  0
  •   Pieter van Ginkel    15 年前

    你的解决方案看起来确实不错,没有什么问题。

    关于 Add 添加 你指的是:

    int System.Collections.IList.Add(Object item)
    {
        try {
            Add((T) item);
        }
        catch (InvalidCastException) {
            throw ...;
        }
    
        return Count - 1;
    }
    

        4
  •  0
  •   Aliostad    15 年前

    我喜欢第二种方法。

       Type itemType = typeof (object);
       if(list.GetType().GetGenericArguments().Length>0)
       {
           itemType = list.GetType().GetGenericArguments()[0];
       }
    
       for (int i = 0; i < recordCount; i++)
       {
          if(record.GetType().IsInstanceOfType(itemType))
       }