2010-01-04 55 views
11

如果我有對象A實現ISomeInterface轉換清單列表的接口

我爲什麼不能做到這一點:

List<objectA> list = (some list of objectAs . . .) 

List<ISomeInterface> interfaceList = new List<ISomeInterface>(list); 

爲什麼我不能粘在列表進入interfaceList構造?有什麼解決方法嗎?

回答

23

在C#3.0 + 3.5的.Net和高達你可以這樣做解決這個問題下面

List<ISomeInterface> interfaceList = new List<ISomeInterface>(list.Cast<ISomeInterface>()); 

之所以這樣不起作用的是,在這種情況下,構造函數List<ISomeInterface>需要一個IEnumerable<ISomeInterface>。列表變量的類型雖然只能轉換爲IEnumerable<objectA>。儘管objectA可轉換爲ISomeInterface,但IEnumerable<objectA>型不可轉換爲IEnumerable<ISomeInterface>

雖然在C#4.0中進行了修改,但它爲語言添加了Co和Contravariance支持並允許進行此類轉換。

+1

@itowlson,這是用戶在樣本中做的事情。他們沒有指定添加行爲是所需解決方案的一部分。 – JaredPar 2010-01-04 05:52:33

+1

你的意思是.NET 3.5,而不是C#3.5。 – 2010-01-04 06:26:26

1

這是在C#4.0中處理的,你不能在C#3.5中直接執行此操作。然而,你可以從這個列表中創建一個新列表,並使用一個擴展操作符或foreach來乾淨地完成它,儘管它比C#4中的 協變性 協變性提供的類型要慢(儘管得到這些錯誤)。

+1

見我來賈裏德評論 - 沒有C#3.5這樣的東西。 – 2010-01-04 06:27:41

+0

Arg,讓我想起Futurama中的美男。儘管說Linq WAS是一種語言變化,並且直到C#3.5才被引入,所以C#是2.0,直到它被賦予了linq擴展,WCF只是3.0中的一個框架升級。 – Spence 2010-01-04 20:37:38

3

最簡單的&短的方法是:

var interfaceList = list.Cast<ISomeInterface>().ToList() 

OR

List<ISomeInterface> interfaceList = list.Cast<ISomeInterface>().ToList() 

上述兩個示例代碼都是平等的,你可以用你想每一個...

+0

使用ToList()的右側是個好主意! 但請注意,使用var你隱藏變量的實際類型,這是不好的做法。 List interfaceList = list.Cast ()。ToList(); 所以我去使用這種形式作爲最清晰,最短的版本 – 2015-12-26 12:41:58

+0

@KovácsEde,根據你提到的點,我添加了第二種方式來回答這個問題,但他們都是平等的。當我們使用'var'時,實際上我們正在以更短的格式編寫我們的代碼,並且總是可以通過查看'='的右側來識別變量的類型。另一方面,即使我們使用'var',C#編譯器也足以識別變量的實際類型。所以如果你想要更短的語法,使用'var'並且從'='右邊的代碼中識別變量類型,否則你可以使用第二種格式。 – RAM 2015-12-29 14:31:27