2010-11-25 15 views
2

方法リストとリストをマージできませんでしたか? OOPはc#generic list 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

私の質問の要点は何ですか? –

答えて

4

C#4.0を使用していないと仮定します。 C#の以前のバージョンの

言語がジェネリック型のcontravariance共分散をサポートしていないので、これは動作しません。

学術用語について心配する必要はありません。これは、許可されている分散の種類(バリエーション)の単なる言葉です。

ここでは詳細には良い記事です: http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faq.aspx

この書き、あなたのコードを動作させるには:

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

を使用すると、C#4(.NET 4)を使用している場合、あなたは単にあなたの最後の行にキャストを取り除くことができます... MyType2ががMyTypeであると言う:

list1.AddRange(list2); 

あなたが」

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

あなたがリストにlist2のキャストができない理由は、そのリストが共変ではないです:C#3(.NET 3.5)を使用して再、あなたはキャストを使用して()LINQの拡張機能を必要としています。あなたは、これはここに当てはまらない理由の良い説明を見つけることができます:最初の行の作品

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

理由はAddRangeは、()のIEnumerableを取り、IEnumerableをは共変であるということです。 .NET 3.5はジェネリックコレクションの共分散を実装していないため、C#3のCast()が必要です。

0

おそらく、あなたができればMyTypeへの明示的なキャストと一緒に、LINQを使用してみてくださいを。 C#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

を使用してMyType2ががMyTypeですが、List<MyType2>List<MyType>ではありませんので、あなたはそれを行うことはできません。 2 List<XXX>タイプの間に継承関係はありません。

LINQのキャストメソッドを使用すると、各要素を必要なタイプにキャストすることができます。

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