简体   繁体   English

有效地创建List <ClassB> 从列表 <ClassA> ?

[英]efficiently creating List<ClassB> from List<ClassA>?

I have objects from ClassA and want to use them to create objects of ClassB. 我有来自ClassA的对象,并希望使用它们来创建ClassB的对象。 I know how to do that if I'm just dealing with one object at a time: 如果我一次只处理一个对象,我知道该怎么做:

ClassA object1 = new ClassA();
ClassB object2 = new ClassB(object1);

class ClassA
{
    public DateTime Timestamp;
    public double X;
    public double Y;
    public double Z;

    public ClassA()
    {
       // other stuff
    }
}

class ClassB
{
    public DateTime Timestamp;
    public double X;

    public ClassB(ClassA A)
    {
        Timestamp = A.Timestamp;
        X = A.X;
    }
}

However, I'm looking for the best way to do it with lists of objects. 但是,我正在寻找使用对象列表的最佳方法。 I want to take the list of type ClassA, and create a list of type ClassB: 我想获取ClassA类型的列表,并创建一个ClassB类型的列表:

List<ClassA> list_of_classA = new List<ClassA>();
List<ClassB> list_of_classB = ????

除了Markus演示的查询样式语法之外,您还可以使用lambda样式语法将ClassA列表投影到ClassB

var listOfClassB = list_of_classA.Select(x => new ClassB(x)).ToList()

You can use Linq to project the list to a new list of type ClassB : 您可以使用Linq将列表投影到ClassB类型的新列表:

List<ClassB> list_of_classB = (from x 
                               in list_of_classA
                               select new ClassB(x)).ToList();

To start, you can find a lot of good samples on Linq here . 首先,你可以在这里找到很多关于Linq的好样本。

Just to throw in a 3rd way to do this: 只是为了做第三种方式:

List<ClassA> list_of_classA = new List<ClassA>();
List<ClassB> list_of_classB = new List<ClassB>();

foreach (ClassA item in list_of_classA)
        {
            list_of_classB.Add(new ClassB(item));
        }

This will accomplish the same thing without using Linq or Lambda expressions. 这将完成相同的事情而不使用Linq或Lambda表达式。 If possible, you would most likely want to use one of the other 2 answers provided. 如果可能,您很可能希望使用提供的其他2个答案中的一个。 However if you are unfamiliar with Linq or Lambda expressions then this may be helpful. 但是,如果您不熟悉Linq或Lambda表达式,那么这可能会有所帮助。

You most likely want to use Select as others have suggested 你很可能想要像其他人建议的那样使用Select

That said, if the only thing you want to do is to do conversions of lists and performance is very important then List has a method called ConvertAll that you could use. 也就是说,如果你想做的唯一事情就是对列表进行转换并且性能非常重要,那么List有一个你可以使用的名为ConvertAll的方法。

List<ClassA> list_of_classA = new List<ClassA>();
List<ClassB> list_of_classB = list_of_classA.ConvertAll((ClassA a) => new ClassB(a));

You can read more about the differences between using Select and ConvertAll here with regards to performance and here with regards to their differences otherwise. 你可以阅读更多有关使用选择并ConvertAll之间的差异在这里与性能有关的,并在这里与问候,否则他们之间的分歧。

Since ConvertAll is the less generic one (only works for Lists) it should be faster than the Select option that is more generic. 由于ConvertAll不是通用的(仅适用于列表),因此它应该比更通用的Select选项更快。 I tried to disprove this idea by doing a few tests. 我试着通过做一些测试来反驳这个想法。

I created a list with 5 and 10 million objects in the A-list and tested the ConvertAll and Select options and got these results: 我在A列表中创建了一个包含5和1000万个对象的列表,并测试了ConvertAll和Select选项并获得了以下结果:

在此输入图像描述 在此输入图像描述

Where the y-axis is in ms. y轴以ms为单位。

So the data seems to suggest that ConvertAll is, in fact, a bit faster. 所以数据似乎表明ConvertAll实际上要快一点。 However, my code might have some issues that cause these differences so take this with a grain of salt. 但是,我的代码可能会有一些导致这些差异的问题,所以请耐心等待。

Here is the code I used. 这是我使用的代码。 Compiled for release to x64. 编译发布到x64。 (also modified ListA so that it actually had a proper constructor) (还修改了ListA,以便它实际上有一个合适的构造函数)

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace lekstuga
{
    class Program
    {
        static void Main(string[] args)
        {
            int loops = 10000000;

            for (var n = 0; n < 4; n++)
            {

                Stopwatch stopwatch;

                List<ClassA> listOfClassA2 = new List<ClassA>();
                List<ClassB> listOfClassB2 = new List<ClassB>();

                for (int i = 0; i < loops; i++)
                {
                    listOfClassA2.Add(new ClassA(DateTime.Now, 1, 2, 3));
                }

                stopwatch = Stopwatch.StartNew(); //creates and start the instance of Stopwatch
                listOfClassB2 = listOfClassA2.ConvertAll((ClassA a) => new ClassB(a));
                stopwatch.Stop();

                Console.WriteLine("ConvertAll " + stopwatch.ElapsedMilliseconds + "ms");


                List<ClassA> listOfClassA = new List<ClassA>();
                List<ClassB> listOfClassB = new List<ClassB>();

                for (int i = 0; i < loops; i++)
                {
                    listOfClassA.Add(new ClassA(DateTime.Now, 1, 2, 3));
                }

                stopwatch = Stopwatch.StartNew(); //creates and start the instance of Stopwatch
                listOfClassB = listOfClassA.Select(x => new ClassB(x)).ToList();
                stopwatch.Stop();

                Console.WriteLine("Select " + stopwatch.ElapsedMilliseconds + "ms");
            }
            Console.ReadLine();
        }

        class ClassA
        {
            public DateTime Timestamp;
            public double X;
            public double Y;
            public double Z;

            public ClassA(DateTime t, double x, double y, double z)
            {
                Timestamp = t;
                X = x;
                Y = y;
                Z = z;
            }
        }

        class ClassB
        {
            public DateTime Timestamp;
            public double X;

            public ClassB(ClassA A)
            {
                Timestamp = A.Timestamp;
                X = A.X;
            }
        }
    }
}

Finally, a note on Select, while it is lazy and does not execute before actually needed the use of .ToList() forces LINQ to calculate the data right away so Select and ConvertAll are comparable in this respect. 最后,关于Select的注释,虽然它是惰性的,但在实际需要使用之前不执行.ToList()会强制LINQ立即计算数据,因此Select和ConvertAll在这方面具有可比性。

暂无
暂无

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

相关问题 当ClassB从ClassA继承时,如何将List <ClassB>转换为List <ClassA>? - How to cast List<ClassB> to List<ClassA> when ClassB inherits from ClassA? 从ClassA转换为ClassB的设计指南 - Design guidelines for converting from ClassA to ClassB 如何使用现有的重载映射函数创建将ClassA列表转换为ClassB的泛型函数。 (C#) - How can I create a generic function that converts a list of ClassA to ClassB, using existing overloaded mapping functions. (C#) 将ClassA中的事件处理程序添加到ClassB中调用的事件中 - Add event handler from ClassA to an event called in ClassB 将 ClassA.Method() 调用为 ClassB.Method() 但只影响 ClassA 值,两个类都源自相同的 BaseClass - Calling a ClassA.Method() as ClassB.Method() but only affecting ClassA values, both classes are deriving from the same BaseClass ClassB继承ClassA。 如何检查ClassA objA是否为ClassB类型,然后将objA转换为ClassB? - ClassB inherits ClassA. How do I check if ClassA objA is of ClassB type and then convert objA to ClassB? 无法转换列表 <ClassA> 列出 <T> - Cannot convert List<ClassA> to List<T> ClassA中的方法是否可能由ClassB中的事件触发? - Is it possible for a method in ClassA to be triggered by an event in ClassB? “ClassA c =新的ClassB`声明可能吗? - Is `ClassA c = new ClassB` declaration possible? 将C#通用约束指定为ClassA或ClassB? - Specify a C# Generic Constraint to be of ClassA OR ClassB?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM