2013-08-01 76 views
1

例子:從列表<T>繼承類型不能與列表分配<T>

 public class ListInheritanceTest 
     { 
      public void Test1() 
      { 
       List<string> list = new List<string>(); 
       MyList myList = list; 
      } 
     } 
     public class MyList : List<string> 
     { 
     } 

MyList myList = list有錯誤「無法隱式轉換類型‘System.Collections.Generic.List’到‘ConsoleTest.MyList’」

我該如何解決這個問題?謝謝。

----編輯----
我不問它爲什麼會給出錯誤。我想知道什麼是使分配工作的解決方法。 上面的代碼只是一個簡單的例子。目的是在我的代碼中將所有List<SomeType>轉換爲MyList,而不會引入任何後向不兼容。

--- 2nd編輯----

讓我改述一下這個問題。假設我在上面的代碼中以相同的方式定義了MyList。 List<string>分配給MyList最簡單的方法是什麼?

我知道

  foreach(var item in list) 
      mylist.Add(item) 

總是工作。只是尋找更優雅的東西。

+4

'MyList'延伸'名單',所以MYLIST是'列表'。 '另一方面,列表'不是'MyList',不能被分配給一個。 –

+0

您需要將列表中的項目添加到mylist – Sayse

+0

'MyList myList = new MyList();'如果這不是答案,您想要做什麼? –

回答

5

我該如何解決這個問題?

更改您的設計。你不能沮喪 - 一個MyList a List<string>但反之亦然。

public class ListInheritanceTest 
{ 
    public void Test1() 
    { 
     List<string> list = new List<string>(); 
     MyList myList = new MyList(list); // copy the items in the list 
    } 
} 
public class MyList : List<string> 
{ 
    public MyList(IEnumerable<string> list) : base(list) {} // reuse the List<T> copy constructor 
} 

的目的是將所有List轉換爲MyList的代碼,而無需:您可以通過接受任何IEnumerable<T>List<T>拷貝構造函數(其中包括一個List<string>)重新使用複製的項目到新名單引入任何落後的不兼容性。

再次,你不能。 A List不是MyList。你可以做的最好的是通過使用複製構造函數或其他方法將列表轉換爲MyList

什麼是分配給List<string>MyList最簡單的方法。

不能。 A List<string>不一定是 a MyList。以與Cat不是Tiger相同的方式。它可能是,但你不能只是是,並把它當作它。

請注意,如果您創建列表爲MyList(例如List<T> newList = new MyList()),那麼你可以安全施放它。事實上,你可以在其他地方使用它,就好像它是一個List<string>(因爲它是!)但是你不能安全地將任意List<string>轉換爲MyList。期。

+0

我認爲這可能是將列表複製到MyList的最佳方式 – Jimbo

3

你不能這樣做。試想一下:

public class MyList : List<string> 
{ 
    public string DoSomething() 
    { 
     return "Something"; 
    } 
} 

//... 

List<string> l = new List<string>(); 
((MyList)l).DoSomething(); // ERROR - List<string> does not define DoSomething()! 
0

如果沒有顯式強制轉換,則無法將基類對象分配給派生類。這裏有兩種方法可以做到這一點:

MyList myList = (MyList) list; // This will throw an exception if it can't be done. 
    MyList myList = list as MyList; // This will return null if it can't be done. 

但是你真的需要考慮你爲什麼要這樣做。如果您繼續使用其他屬性或字段開發MyList,您將如何處理從List到MyList的投射?那些其他的財產和領域將如何處理?

爲什麼你不能只是:

MyList myList = new MyList(); 

?我懷疑還有一些其他需要考慮的設計因素,例如使用接口。


編輯:根據您的第二次編輯,您想要將列表中的所有項目分配給MyList嗎?在這種情況下,你可以:

myList.AddRange(list); 
+0

您可以始終將類的實例分配給作爲其超類聲明的變量,而無需進行明確的轉換(但這不是發生在此處)。 –

+0

哎呀,是的,我在努力登錄時混淆了我的條款。讓我解決這個問題... – Kylon

1

我認爲這解決了問題,並允許列表中的任何國王(字符串,整數,.....)加入:

public class ListInheritanceTest 
    { 
     public void Test1() 
     { 
      List<string> list = new List<string>() { "1", "2", "3", "4", "5" }; 

      MyList<string> myList = new MyList<string>(); 
      myList.AddRange(list); 

      foreach (var item in myList) 
      { 
       Console.WriteLine(item); 
      } 
     } 
    } 
    public class MyList<T> : List<T> 
    { 
    } 

另一種方式,因爲MYLIST從列表導出(這將適用於一些特定的情況下,對於上面這個例子是更好):

public class ListInheritanceTest 
    { 
     public void Test1() 
     { 
      List<string> list = new MyList<string> { "1", "2", "3", "4", "5" }; 

      MyList<string> myList = (MyList<string>) list; 


      foreach (var item in myList) 
      { 
       Console.WriteLine(item); 
      } 
     } 
    } 
    public class MyList<T> : List<T> 
    { 
    } 
+0

AddRange是完成這項工作的好方法! – Jimbo

+0

thnx,我會用另一種方式編輯,但這會是「更好」。 – terrybozzio

0

如果要避免複製列表中,您將不得不改變MYLIST位。這將允許您隨時包裝您的列表並且具有相同的界面,而不需要複製元素。

class MyList : IList<string> 
{ 
    private readonly List<string> theList; 

    public MyList(List<string> list) 
    { 
     theList = list; 
    } 

    // Implement the IList<string> interface by 
    // calling the same methods on theList 
} 

List<string> oldList = new List<string>(); 
MyList wrapper = new MyList(oldList); 
相關問題