开发者

c# generic list merge

Way I could not merge List and List? OOP says MyType2 is 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);
        开发者_如何学Python    }           

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


I'm going to assume that you're not using C# 4.0.

In earlier versions of C#, this won't work because the language doesn't support contravariance and covariance of generic types.

Don't worry about the academic jargon - they're just the terms for the kinds of variance (i.e. variation) permitted.

Here's a good article on the details: http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faq.aspx

To make your code work, write this:

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


If you're using C#4 (.NET 4), you can simply remove the cast in your last line:

list1.AddRange(list2);

If you're using C#3 (.NET 3.5), you need to using the Cast() LINQ extension:

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

The reason that you can't cast list2 to List is that List is not covariant. You can find a good explanation of why this is not the case here:

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

The reason the first line works is that AddRange() takes an IEnumerable and IEnumerable is covariant. .NET 3.5 does not implement covariance of generic collections and hence the need for the Cast() in C#3.


Perhaps try using LINQ if you can, along with an explicit cast to MyType. Using 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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜