C# 高效地创建列表<;B类>;从列表<;ClassA>;?
我有来自ClassA的对象,希望使用它们来创建ClassB的对象。如果我一次只处理一个对象,我知道怎么做:C# 高效地创建列表<;B类>;从列表<;ClassA>;?,c#,list,constructor,C#,List,Constructor,我有来自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 Class
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 = ????
List List\u of_classA=new List();
列出类别B的列表=????
您可以使用Linq将列表投影到类型为ClassB
的新列表中:
List<ClassB> list_of_classB = (from x
in list_of_classA
select new ClassB(x)).ToList();
List\u of_classB=(从x开始)
在类别A的列表中
选择new ClassB(x)).ToList();
首先,您可以在Linq上找到许多好的示例。除了Markus演示的查询样式语法之外,您还可以使用lambda样式语法将ClassA列表投影到ClassB
var listOfClassB = list_of_classA.Select(x => new ClassB(x)).ToList()
只是想用第三种方法来实现这一点:
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));
}
List List\u of_classA=new List();
List List of_classB=新列表();
foreach(类别A列表中的类别A项目)
{
添加(新类别B(项目));
}
这将在不使用Linq或Lambda表达式的情况下完成相同的任务。如果可能,您很可能希望使用提供的其他两个答案中的一个。但是,如果您不熟悉Linq或Lambda表达式,这可能会有所帮助。您很可能希望按照其他人的建议使用Select 这就是说,如果您只想做列表转换,而性能非常重要,那么List有一个方法,您可以使用它
List<ClassA> list_of_classA = new List<ClassA>();
List<ClassB> list_of_classB = list_of_classA.ConvertAll((ClassA a) => new ClassB(a));
List List\u of_classA=new List();
List_of_classB=List_of_classA.ConvertAll((classA a)=>新classB(a));
您可以阅读有关使用Select和ConvertAll之间差异的更多信息
在性能方面以及在其他方面的差异方面
由于ConvertAll是不太通用的选项(仅适用于列表),因此它应该比更通用的Select选项更快。我试图通过做一些测试来反驳这个观点
我在a-list中创建了一个包含500万和1000万个对象的列表,并测试了ConvertAll和Select选项,得到了以下结果:
其中y轴以毫秒为单位
因此,数据似乎表明ConvertAll实际上要快一点。然而,我的代码可能存在一些导致这些差异的问题,因此对此持保留态度
这是我使用的代码。编译后发布到x64。(还修改了ListA,使其实际上具有正确的构造函数)
使用系统;
使用System.Collections.Generic;
使用系统诊断;
使用System.Linq;
名称空间lekstuga
{
班级计划
{
静态void Main(字符串[]参数)
{
int循环=10000000;
对于(var n=0;n<4;n++)
{
秒表;
List listOfClassA2=新列表();
List listOfClassB2=新列表();
for(int i=0;inew ClassB(a));
秒表;
Console.WriteLine(“ConvertAll”+stopwatch.elapsedmillyses+“ms”);
List listOfClassA=新列表();
List listOfClassB=新列表();
for(int i=0;inewclassb(x)).ToList();
秒表;
Console.WriteLine(“选择”+stopwatch.ElapsedMilliseconds+“毫秒”);
}
Console.ReadLine();
}
甲级
{
公共日期时间戳;
公共双X;
公共双Y;
公共双Z;
公共类A(日期时间t,双x,双y,双z)
{
时间戳=t;
X=X;
Y=Y;
Z=Z;
}
}
B类
{
公共日期时间戳;
公共双X;
公共B类(A类)
{
时间戳=A.时间戳;
X=A.X;
}
}
}
}
最后,关于Select的一个注意事项是,虽然它是惰性的,并且在实际需要使用.ToList()之前不会执行,但它会强制LINQ立即计算数据,因此Select和ConvertAll在这方面是可比较的。假设使用相同的构造函数,您可以
列出\u classA.Select(classA=>new ClassB(classA)).ToList()
?谢谢。根据System.Diagnostics.StopWatch,就我而言,该方法运行良好,速度与其他方法一样快。现在开始阅读lambda风格的语法。谢谢
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;
}
}
}
}