可以在泛型方法中使用IList但不能使用List

时间:2013-03-24 20:13:33

标签: c# list generics interface ilist

我正在尝试创建一个方法,该方法返回用户想要的任何类型的列表。要做到这一点,我使用的是泛型,我不太熟悉,所以这个问题可能很明显。问题是此代码不起作用并抛出错误消息Cannot convert type Systems.Collections.Generic.List<CatalogueLibrary.Categories.Brand> to Systems.Collection.Generic.List<T>

private List<T> ConvertToList<T>(Category cat)
{            
     switch (cat)
     {
         case Category.Brands:
             return (List<T>)collection.Brands.ToList<Brand>();

     }
    ...
}

但如果我改用IList,则没有错误。

private IList<T> ConvertToList<T>(Category cat)
{            
     switch (cat)
     {
         case Category.Brands:
             return (IList<T>)collection.Brands.ToList<Brand>();

     }
     ...
} 

在这种情况下,为什么我可以使用IList而不使用List? collection.Brands从第三方库返回BrandCollection类型,所以我不知道它是如何创建的。可能是BrandCollection可能来自IList(只是猜测它确实如此),因此它可以转换为它而不是正常的List?

1 个答案:

答案 0 :(得分:9)

由于T没有约束,因此只能在编译时将其转换为object。编译器不会检查对接口类型的强制转换,因为理论上可能会创建一个实现IList<object>并继承List<Brand>的新类。但是,对List<T>的强制转换将失败,因为已知无法创建一个继承List<object>List<Brand>的类。但是,在您的情况下,您通过T语句知道switch类型是什么,并希望强制执行转换。要执行此操作,请首先转发object,如下所示:

private List<T> ConvertToList<T>(Category cat)
{            
    switch (cat)
    {
        case Category.Brands:
            return (List<T>)(object)collection.Brands.ToList<Brand>();
    }
}

但是,更大的设计问题是,当您拥有T的已知类型的离散列表时,泛型不是最佳选择。当T可以是任何东西,或者被限制为基本类型或接口时,泛型更好。在这里,你最好只为switch语句的每个分支编写一个单独的方法:

private List<Brand> ConvertToBrandList()
{
    return collection.Brands.ToList<Brand>();
}

如果没有这个,你的类型安全性很小。如果有人使用ConvertToList<int>(Category.Brands)调用您的方法,该怎么办?