7

我正在尝试创建一个方法,该方法返回用户想要的任何类型的列表。为此,我使用了泛型,我不太熟悉,所以这个问题可能很明显。问题是此代码不起作用并抛出错误消息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?BrandCollectioncollection.Brands从第三方库返回一个类型,所以我不知道它是如何创建的。可能是BrandCollection从 IList 派生的(只是猜测它确实如此),因此可以将其转换为它,但不能转换为普通的 List?

4

1 回答 1

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>();
    }
}

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

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

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

于 2013-03-24T20:35:22.320 回答