我有来自ClassA的对象,并希望使用它们来创建ClassB的对象。如果我一次只处理一个对象,我知道如何做到这一点:
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;
}
}
但是,我正在寻找使用对象列表的最佳方法。我想获取类型ClassA的列表,并创建一个类型为ClassB的列表:
List<ClassA> list_of_classA = new List<ClassA>();
List<ClassB> list_of_classB = ????
答案 0 :(得分:5)
除了Markus演示的查询样式语法之外,您还可以使用lambda样式语法将ClassA列表投影到ClassB
var listOfClassB = list_of_classA.Select(x => new ClassB(x)).ToList()
答案 1 :(得分:3)
您可以使用Linq将列表投影到类型为ClassB
的新列表:
List<ClassB> list_of_classB = (from x
in list_of_classA
select new ClassB(x)).ToList();
首先,你可以在Linq here上找到很多好的样本。
答案 2 :(得分:2)
只是为了做第三种方式:
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));
}
如果不使用Linq或Lambda表达式,这将完成同样的事情。如果可能,您很可能希望使用提供的其他2个答案中的一个。但是,如果您不熟悉Linq或Lambda表达式,那么这可能会有所帮助。
答案 3 :(得分:2)
您很可能希望像其他人建议的那样使用Select
也就是说,如果你想要做的唯一事情就是对列表进行转换并且性能非常重要,那么List有一个你可以使用的方法ConvertAll。
List<ClassA> list_of_classA = new List<ClassA>();
List<ClassB> list_of_classB = list_of_classA.ConvertAll((ClassA a) => new ClassB(a));
您可以阅读有关使用Select和ConvertAll之间差异的更多信息 here关于绩效,here关于他们的差异。
由于ConvertAll是较不通用的(仅适用于列表),因此它应该比更通用的Select选项更快。我尝试通过一些测试来反驳这个想法。
我在A列表中创建了一个包含5和1000万个对象的列表,并测试了ConvertAll和Select选项并获得了这些结果:
y轴以ms为单位。
所以数据似乎表明ConvertAll实际上要快一点。但是,我的代码可能会有一些导致这些差异的问题,所以请耐心等待。
这是我使用的代码。编译发布到x64。 (还修改了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;
}
}
}
}
最后,关于Select的注释,虽然它是懒惰的但在实际需要使用之前不执行.ToList()会强制LINQ立即计算数据,因此Select和ConvertAll在这方面具有可比性。