2013-03-24 46 views
7

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

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(只是猜测它确实),所以它可以转换为它,但不是正常的列表?

+0

你应该把类型约束放在那里!你不能只是围绕着铸造东西。 – antonijn 2013-03-24 20:17:17

+3

你确定你的第二个例子不是'return(IList )collection.Brands.ToList ();'? – Matthew 2013-03-24 20:18:13

+0

我打算在这个工作后看看。我对泛型有点新,所以我认为在后面的情况下它会破坏别的东西:D约束条件是'T:品牌'(和其他类别)吗? – XSL 2013-03-24 20:18:30

回答

9

由于T没有限制,因此只能在编译时转换为object。强制转换为接口类型不被编译器检查,因为理论上可能会创建一个新类,该类实现了IList<object>并继承了List<Brand>。然而,转换到List<T>将失败,因为已知不能创建继承List<object>List<Brand>的类。然而,就你而言,你知道T类型是通过你的switch声明并希望强制演员。

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

更大的设计问题在这里,虽然是仿制药是不是最好的选择,当你有已知类型的用于T离散列表:要做到这一点,通过object首先如下投。当T既可以是任何东西,也可以限制为基本类型或接口时,泛型更好。在这里,你会离开只是写一个单独的方法switch语句的每个分支更好:

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

如果没有这个,你只有很少类型安全。如果有人用ConvertToList<int>(Category.Brands)打电话给你的方法怎么办?

+0

感谢您的解释。尽管'object'方法起作用了,我会去找个别的方法路线。我只是发现它是一个封闭的类,我无法将其限制为“品牌”。 – XSL 2013-03-24 20:50:01

+0

+1。我认为真正的原因是由于C#参考6.2.4:“明确的参考转换是......\t从*任何类类型S *到*任何接口类型T *,只要S不密封并且提供S不执行T. – 2013-03-24 20:51:50

相关问题