c#通用列表合并

时间:2010-11-25 18:29:59

标签: c# collections merge

方式我无法合并列表和列表? OOP说MyType2是MyType ......

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);
        }
    }
}

4 个答案:

答案 0 :(得分:5)

我将假设你没有使用C#4.0。

在早期版本的C#中,这不起作用,因为该语言不支持泛型类型的逆变协方差

不要担心学术术语 - 它们只是允许的各种差异(即变异)的术语。

这是一篇关于细节的好文章: http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faq.aspx

要使代码正常工作,请写下:

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

答案 1 :(得分:2)

如果您使用的是C#4(.NET 4),则只需删除最后一行中的强制转换:

list1.AddRange(list2);

如果您使用的是C#3(.NET 3.5),则需要使用Cast()LINQ扩展名:

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

您无法将list2强制转换为List的原因是List不是协变的。你可以找到一个很好的解释,说明为什么不是这种情况:

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()。

答案 2 :(得分:0)

如果可以,可以尝试使用LINQ,以及对MyType的明确强制转换。使用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>());

答案 3 :(得分:0)

您不能这样做,因为MyType2是MyType,但List<MyType2>不是List<MyType>。 2 List<XXX>种类之间没有继承关系。

您可以使用LINQ的Cast方法轻松实现复制,该方法会将每个元素强制转换为您想要的类型。

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