2011-05-16 161 views
26

我有一个接口定义为:如何将列表<interface>转换为列表<concrete>?

public interface MyInterface { 
    object foo { get; set; }; 
} 

和一个类实现该接口:

public class MyClass : MyInterface { 
    object foo { get; set; } 
} 

我然后创建返回ICollection的像这样的函数:

public ICollection<MyClass> Classes() { 
    List<MyClass> value; 

    List<MyInterface> list = new List<MyInterface>(
     new MyInterface[] { 
      new MyClass { 
       ID = 1 
      }, 
      new MyClass { 
       ID = 1 
      }, 
      new MyClass { 
       ID = 1 
      } 
     }); 

    value = new List<MyClass>((IEnumerable<MyClass>) list); 

    return value; 
} 

它会编译但会抛出一个

无法投射类型为 'System.Collections.Generic.List 1[MyInterface]' to type 'System.Collections.Generic.IEnumerable 1 [MyClass]'的对象。

异常。我究竟做错了什么?

回答

43

一个List<MyInterface>不能转换为一般List<MyClass>,因为第一个列表可能包含实现MyInterface但实际上不是对象MyClass类型的对象。

然而,由于你的情况,你知道你是怎么构成的名单,可以肯定的是它只包含MyClass对象,你可以做到这一点使用LINQ的:

return list.ConvertAll(o => (MyClass)o); 
+6

这将工作在.Net 2.0+而不仅仅是LINQ,因为System.Collections.Generic.List <>直接支持ConvertAll ()。 – 2011-05-16 15:44:12

+0

谢谢,@Ritch。我认为'ConvertAll'是一个Linq方法,但我没有打扰到检查。 – 2011-05-16 15:47:35

+0

这个伎俩!感谢JSBangs。 – acermate433s 2011-05-16 15:49:35

24

List<MyInterface>显然不是一个List<MyClass>

认为:

interface IAnimal { } 

class Cat : IAnimal { } 
class Dog : IAnimal { } 

var list = new List<IAnimal> { new Cat(), new Dog() }; 

然后

var cats = (List<Cat>)list; 

荒谬!

此外,

var cats = list.Cast<Cat>(); 

荒谬!

而且

var cats = list.ConvertAll(x => (Cat)x); 

荒谬!

相反,你可以说

var cats = list.OfType<Cat>(); 
+0

我明白了。我很困惑,因为你可以为它的具体类加入一个接口。谢谢。 – acermate433s 2011-05-16 15:55:30

0

我发现Automapper转换接口,具体的类非常有用的。

相关问题