简体   繁体   English

C#通用列表合并

[英]c# generic list merge

Way I could not merge List and List? 我无法合并列表和列表? OOP says MyType2 is MyType... 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);
        }
    }
}

I'm going to assume that you're not using C# 4.0. 我将假设您没有使用C#4.0。

In earlier versions of C#, this won't work because the language doesn't support contravariance and covariance of generic types. 在早期版本的C#,这是行不通的,因为语言不支持泛型类型的逆变协方差

Don't worry about the academic jargon - they're just the terms for the kinds of variance (ie 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 这是一篇关于细节的好文章: 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: 如果您使用的是C#4(.NET 4),则只需在最后一行中删除演员表:

list1.AddRange(list2);

If you're using C#3 (.NET 3.5), you need to using the Cast() LINQ extension: 如果使用的是C#3(.NET 3.5),则需要使用Cast()LINQ扩展:

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

The reason that you can't cast list2 to List is that List is not covariant. 您不能将list2强制转换为List的原因是List不是协变的。 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 在C#中,为什么不能将List <string>对象存储在List <object>变量中

The reason the first line works is that AddRange() takes an IEnumerable and IEnumerable is covariant. 第一行起作用的原因是AddRange()采用IEnumerable,而IEnumerable是协变的。 .NET 3.5 does not implement covariance of generic collections and hence the need for the Cast() in C#3. .NET 3.5没有实现通用集合的协方差,因此在C#3中需要Cast()。

Perhaps try using LINQ if you can, along with an explicit cast to MyType . 如果可以的话,也许尝试使用LINQ以及对MyType的显式转换。 Using C# 4. 使用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>());

You can't do that because MyType2 is MyType, but List<MyType2> is not List<MyType> . 您不能这样做,因为MyType2是MyType,但是List<MyType2>不是List<MyType> There are no inheritance relationship between 2 List<XXX> types. 2个List<XXX>类型之间没有继承关系。

You can easily achive copying by using LINQ's Cast method which will cast each element to type you want. 您可以使用LINQ的Cast方法轻松实现复制,该方法会将每个元素转换为所需的类型。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM