2016-11-20 11 views
2

在C#中,我有一個類MyObj,它實現了一個接口IMyInterface在C#中,爲什麼從對象列表到接口列表的轉換拋出異常?

我現在有MyObj中類的列表的集合:

IEnumerable<List<MyObj>> myObjGroups 

,我希望把它轉換/轉換爲

IEnumerable<List<IMyInterface>> myInterfaceGroups 

,一切我都試過已拋出異常。

「」類型的異常出現在System.Core.dll但在用戶代碼中沒有處理 其他信息:無法轉換類型的對象「System.Collections.Generic.List ` 1 [MyObj中]'鍵入'System.Collections.Generic.List ` 1 [IMyInterface]'。

我曾嘗試:

IEnumerable<List<IMyInterface>> myInterfaceGroups= new List<List<IMyInterface>>(myObjGroups.Cast<List<IMyInterface>>()); 

和:

IEnumerable<List<IMyInterface>> myList = myObjGroups.Cast<List<IMyInterface>>(); 

兩者似乎在運行時拋出異常。

關於我在做什麼錯的任何建議?

+2

'名單'不是'名單'所以演員表無效。你可以使用IEnumerable >'。如果你需要內部列表然後'myObjGroups.Select(l => l.Cast ()。ToList())'。 – Lee

+1

就像@李說的那樣,一個'List '不是'List '。這是因爲'List '在'T'中不是協變的(它不是'List ')。那是因爲這個類有成員,比如'Add'方法,使得協變不可能。一個接口,例如'IReadOnlyList '可以工作。如果只是'MyObj'是一個實現'IMyInterface'的引用類型,'IReadOnlyList '是一個'IReadOnlyList '。 'IEnumerable '是協變的。 –

回答

2

試試以下的方法:

IEnumerable<List<IMyInterface>> myInterfaceGroups = myObjGroups 
    .Select(l => l.Select(o => (IMyInterface)o).ToList()); 

或者如果你喜歡使用Cast<T>()擴展方法:

IEnumerable<List<IMyInterface>> myInterfaceGroups = myObjGroups 
    .Select(l => l.Cast<IMyInterface>().ToList()); 

編輯:解釋有點

爲了更好地理解爲什麼你有沒有得到InvalidCastException異常,讓我們嘗試分解你的原始表達式:

IEnumerable<List<IMyInterface>> myInterfaceGroups = 
    new List<List<IMyInterface>>(myObjGroups.Cast<List<IMyInterface>>()); 

這相當於:

IEnumerable<List<IMyInterface>> myObjGroupsAsInterfaceList = myObjGroups 
    .Cast<List<IMyInterface>>() 
    .ToList(); 

IEnumerable<List<IMyInterface>> myInterfaceGroups = new List<List<IMyInterface>>(myObjGroupsAsInterfaceList); 

Cast<T>()擴展方法通過項目只是迭代並試圖投每個項目鍵入T。我們可以更換Cast<T>()擴展方法的功能結合ToList<T>()與下面的代碼片段:

List<List<IMyInterface>> myObjGroupsAsInterfaceList = new List<List<IMyInterface>>(); 
foreach (List<MyObj> myObjGroup in myObjGroups) 
{ 
    List<IMyInterface> myObjGroupAsInterface = myObjGroup; // Compile error! 
    myObjGroupsAsInterfaceList.Add(myObjGroupAsInterface); 
} 

所以根本的問題是,你不能一個List<MyObj>對象分配給List<IMyInterface>類型的變量。

要找到爲什麼上面是不可能的更多的解釋,採取以下問題一看:C# variance problem: Assigning List<Derived> as List<Base>

0

你做錯了什麼。您不能將IEnumerable轉換爲List。列表是一個實際的數據化數據集合,而運行時需要重複執行IEnumerable以檢索數據。

解決你的問題,你需要轉換到IEnumerable<IMyInterface>

檢查工作小提琴:Here(下同)

public class Program 
{ 
    static IEnumerable<List<MyObj>> Get() 
    { 
     yield return new List<MyObj>(); 
     yield return new List<MyObj>(); 
    } 

    static void Main() 
    { 
     IEnumerable<List<MyObj>> myObjGroups = Get(); 

     var result = myObjGroups.Cast<IEnumerable<IMyInterface>>(); 

     foreach(var val in result) 
      Console.WriteLine(val.Count()); 
    } 
} 
相關問題