2011-05-16 93 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轉換接口,具體的類非常有用的。

相關問題