通过IList后门通用列表

Hom*_*mde 8 c# generics ilist

我有一个场景,其中一个类加载一种类型的对象,由于抽象我不能使用泛型类(泛型往往像癌症一样蔓延:)但我经常想要检索一次通用版本的对象,结果在像这样的代码(简化):

List<SomeClass> items = Storage.LoadItems(filename).OfType<SomeClass>().ToList();
Run Code Online (Sandbox Code Playgroud)

在LoadItems返回List <object>的地方,我意识到,为什么不这样做呢

public void LoadItems(string filename,IList list);
Run Code Online (Sandbox Code Playgroud)

现在我可以这样做

List<SomeClass> items = new  List<SomeClass>();
LoadItems(filename,items);
Run Code Online (Sandbox Code Playgroud)

哪个应该更有效率.由于我可以使用现有的List并添加新项目,因此它似乎也更灵活一些.所以我的问题是,这是一种常见的模式还是你有不同/更好的方法来实现这一目标?

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

编辑 修改模式实际上可能更优雅一些

public IList LoadItems(string filename,IList list=null);
Run Code Online (Sandbox Code Playgroud)

这样你可以流利地使用语句,如果没有传递列表,你可以简单地实例化List <object>

SLa*_*aks 3

List<T>明确实施IList。实现转换为T并调用常规(通用)方法。

因此,只有在显式调用方法时才会进行类型检查IList。例如:

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));
    } 
}
Run Code Online (Sandbox Code Playgroud)

它不使用as关键字,因为它T可能是值类型。只有你写了,
你才能写。as Twhere T : class