2010-11-25 18 views
2

Weise konnte ich Liste und Liste nicht zusammenführen? OOP sagt MyType2 MyType ist ...C# generische Liste merge

using System; 
using System.Collections.Generic; 

namespace two_list_merge 
{ 
    public class MyType 
    { 
     private int _attr1 = 0; 

     public MyType(int i) 
     { 
      Attr1 = i; 
     } 

     public int Attr1 
     { 
      get { return _attr1; } 
      set { _attr1 = value; } 
     } 
    } 

    public class MyType2 : MyType 
    { 
     private int _attr2 = 0; 

     public MyType2(int i, int j) 
      : base(i) 
     { 
      Attr2 = j; 
     } 

     public int Attr2 
     { 
      get { return _attr2; } 
      set { _attr2 = value; } 
     } 
    } 

    class MainClass 
    { 
     public static void Main(string[] args) 
     { 
      int count = 5; 
      List<MyType> list1 = new List<MyType>(); 
      for(int i = 0; i < count; i++) 
      { 
       list1[i] = new MyType(i); 
      } 

      List<MyType2> list2 = new List<MyType2>(); 
      for(int i = 0; i < count; i++) 
      { 
       list1[i] = new MyType2(i, i*2); 
      }   

      list1.AddRange((List<MyType>)list2); 
     } 
    } 
} 
+0

Der Hauptpunkt in meiner Frage ist Weg? –

Antwort

4

Ich gehe davon aus, dass Sie nicht C# 4.0 verwenden.

In früheren Versionen von C#, das wird nicht funktionieren, weil die Sprache nicht Kontra und Kovarianz von generischen Typen unterstützt.

Mach dir keine Sorgen über den akademischen Jargon - sie sind nur die Bedingungen für die Arten der Varianz (d. H. Variation) erlaubt.

Hier ist ein guter Artikel über die Details: http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faq.aspx

Um Ihren Code funktioniert, schreibe dies:

list1.AddRange(list2.Cast<MyType>()); 
2

Wenn Sie C# 4 (.NET 4) verwenden, können Sie einfach die Besetzung in der letzten Zeile entfernen:

list1.AddRange(list2); 

Wenn Sie‘ C# 3 (.NET 3.5) erneut verwenden, müssen Sie die Cast() verwenden LINQ-Erweiterung:

list1.AddRange(list2.Cast<MyType>()); 

Der Grund, dass Sie nicht list2 Liste werfen kann, ist diese Liste ist nicht covariant. Sie können eine gute Erklärung, warum dies hier nicht der Fall ist:

In C#, why can't a List<string> object be stored in a List<object> variable

Der Grund für die erste Zeile funktioniert ist, dass AddRange() nimmt ein IEnumerable und IEnumerable ist covariant. .NET 3.5 implementiert keine Kovarianz generischer Auflistungen und daher die Anforderung für Cast() in C# 3.

0

Vielleicht mit LINQ versuchen, wenn Sie können, zusammen mit einer expliziten Umwandlung in MyType. C mit # 4.

List<MyType> list1 = new List<MyType> 
    { new MyType(1), new MyType(2), new MyType(3)}; 

List<MyType2> list2 = new List<MyType2> 
    { new MyType2(11,123), new MyType2(22,456), new MyType2(33, 789) }; 

var combined = list1.Concat(list2.AsEnumerable<MyType>()); 
0

Sie können nicht tun, weil MyType2 MyType, aber List<MyType2> ist nicht List<MyType>. Es gibt keine Vererbungsbeziehung zwischen 2 List<XXX> Typen.

Sie können mit der LINQ-Cast-Methode, die jedes Element in den gewünschten Typ umwandelt, mühelos kopieren.

list1.AddRange(list2.Cast<MyType>());