2012-01-19 18 views

回答

149

不能它(保留基準身份) - 這將是不安全的。例如:

public interface IFruit {} 

public class Apple : IFruit {} 
public class Banana : IFruit {} 

... 

List<Apple> apples = new List<Apple>(); 
List<IFruit> fruit = apples; // Fortunately not allowed 
fruit.Add(new Banana()); 

// Eek - it's a banana! 
Apple apple = apples[0]; 

現在你可以轉換List<Apple>IEnumerable<IFruit>在.NET 4.0/C#4,由於協方差,但如果你想有一個List<IFruit>你必須創建一個新的名單。例如:

// In .NET 4, using the covariance of IEnumerable<T> 
List<IFruit> fruit = apples.ToList<IFruit>(); 

// In .NET 3.5 
List<IFruit> fruit = apples.Cast<IFruit>().ToList(); 

但這一樣鑄造原名單 - 因爲現在有兩個獨立的名單。這是安全的,但您需要了解在一個列表所做的更改不會在另一個列表中看到。 (修改到對象這些清單是指將要看到的,當然)。

+5

@Downvoter:關心評論? –

+5

就像他們'仍在建築物中! –

+1

做協方差和做新列表之間的區別是什麼();然後在原始列表中添加一個foreach,並將每個項目添加到IFruit列表中?用foreach的方式...對象引用是一樣的,對嗎?所以......如果那是真的,我個人覺得你不能直接把整個表格全部列出來。 ? –

0

其唯一可能的方法是創建新的List<IDic>並傳輸所有元素。

+0

任何評論爲什麼downvoted,因爲一般意義是一樣的所有其他答案? –

+0

我的猜測是你被downvoted,因爲你說只能創建一個新的列表,但其他人已經發布了相反的...不是我的downvote雖然) – musefan

+0

那麼他們確實創建新的列表,但不是與新的運算符不相關不會改變他們所做的事實。 –

4

鑄造iterator和.ToList():

List<IDic> casted = input.Cast<IDic>().ToList()會做的伎倆。

本來我說協變會奏效 - 但正如喬恩正確指出的那樣;不,它不會!

,最初我也愣神不放過ToList()呼叫

+0

'Cast'返回'IEnumerable ',而不是'List ' - 並且,協變*不會*允許這種轉換,因爲它會是不安全的 - 請參閱我的答案。 –

+0

從您鏈接到的頁面:「只有接口類型和委託類型可以具有變體類型參數」 –

+0

@Jon - 在閱讀您的評論之前,我已經意識到'ToList()'丟失了;但是,正如你所顯示的,當然Covariance不起作用!衛生署! –

1

如果你可以使用LINQ,那麼你可以做到這一點...

List<Client> clientList = new List<Client>(); 
List<IDic> list = clientList.Select(c => (IDic)c).ToList(); 
1
List<Client> listOfA = new List<Client>(); 
List<IDic> list = listOfA.Cast<IDic>().ToList(); 
1

我也有這個問題,閱讀喬恩斯基特的回答後,我修改了代碼,使用List<T>使用IEnumerable<T>。雖然這不回答OP的原始問題我如何投List<Client>List<IDic>,它確實避免了這樣做的需要,因此可能會幫助其他遇到此問題的人。這當然假設需要使用List<IDic>的代碼在您的控制之下。

如:

public void ProcessIDic(IEnumerable<IDic> sequence) 
{ 
    // Implementation 
} 

相反的:

public void ProcessIDic(List<IDic> list) 
{ 
    // Implementation 
} 
0

.NET 3.5中,你可以做到以下幾點:

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

在這種情況下列表的構造函數的IEnumerable的。
列表雖然只能轉換爲IEnumerable。即使myObj可能會轉換爲ISomeInterface類型IEnumerable不可轉換爲IEnumerable。

+0

問題是這使得列表的副本,大部分時間你想對原始列表進行操作 – rolls