C# LINQ是效率所必需的新选择

C# LINQ是效率所必需的新选择,c#,linq,C#,Linq,如果我从列表中选择元素的子集,那么通过执行“选择新”仅获取我将使用的属性,我是否获得了任何东西。或者编译器只是对其进行了优化,这样我就不用再为选择新的而烦恼了,例如: var q = from n in TheseGuysHaveABunchOfProperties where n.State == "AK" select new { Name = n.Name, Phone = n.Phone }; q.ToList().ForEach(x => De

如果我从列表中选择元素的子集,那么通过执行“选择新”仅获取我将使用的属性,我是否获得了任何东西。或者编译器只是对其进行了优化,这样我就不用再为
选择新的
而烦恼了,例如:

var q = from n in TheseGuysHaveABunchOfProperties
        where n.State == "AK" 
        select new { Name = n.Name, Phone = n.Phone };

q.ToList().ForEach(x => Debug.WriteLine(x.Name + x.Phone);
vs

var q = from n in TheseGuysHaveABunchOfProperties
        where n.State == "AK" select n;

q.ToList().ForEach(x => Debug.WriteLine(x.Name + x.Phone);

如果您正在对对象执行LINQ,则不会。当您复制和分配更多临时变量时,速度可能会更慢。对于LINQ to SQL,则是另一种方式,即减少从数据库复制的数据量


编辑:描述常见情况。在LINQ to对象的情况下,如果对象的检索成本很高,并且在
select
语句中多次使用,那么复制对象的速度可能会更快。对于LINQ to SQL,请不要选择实际不使用的属性

如果您正在对对象执行LINQ,则不会。当您复制和分配更多临时变量时,速度可能会更慢。对于LINQ to SQL,则是另一种方式,即减少从数据库复制的数据量


编辑:描述常见情况。在LINQ to对象的情况下,如果对象的检索成本很高,并且在
select
语句中多次使用,那么复制对象的速度可能会更快。对于LINQ to SQL,请不要选择实际不使用的属性

通常仅当您要生成新类型(匿名类型)时才使用Select New。这实际上不是效率的问题,而是需要处理什么类型的问题。

通常只有在您想要生成新类型(匿名类型)时才使用Select New。这实际上不是效率的问题,而是你需要处理什么类型的问题。

select new
创建一个匿名类型。如果你不需要它,你可能不应该使用它

更高的效率将为您提供正确的字符串比较:

where String.Equals(m.State, "AK", StringComparison.Ordinal); // or OrdinalIgnoreCase

选择新建
创建匿名类型。如果你不需要它,你可能不应该使用它

更高的效率将为您提供正确的字符串比较:

where String.Equals(m.State, "AK", StringComparison.Ordinal); // or OrdinalIgnoreCase

您绝对想使用
选择新建
。如果执行此操作时,
theseguyshavabunchofproperties
具有大量属性(因此也包含大量数据)。ToList()将完全枚举集合。因此,内存中有一个列表,其中包含每个对象和每个属性

通过在
ToList
之前执行
select new
,列表中的对象将仅具有所需的两个属性


如果可以避免在
ForEach
之前执行
ToList
,则不会出现此问题。当然,内存使用情况等取决于列表的大小和
这些属性中的属性数
您绝对希望使用
选择新属性。如果执行此操作时,
theseguyshavabunchofproperties
具有大量属性(因此也包含大量数据)。ToList()将完全枚举集合。因此,内存中有一个列表,其中包含每个对象和每个属性

通过在
ToList
之前执行
select new
,列表中的对象将仅具有所需的两个属性


如果可以避免在
ForEach
之前执行
ToList
,则不会出现此问题。当然,内存使用等取决于列表的大小和
这些属性中的属性数。首先,@jdv是正确的+我向他道歉。我想补充一点,如果您担心性能,请删除
ToList()
。这是创建数据的副本,只是为了在上面枚举。您现在正在对其枚举两次

相反,通常使用foreach循环:

foreach(var x in q)
    Debug.WriteLine(x.Name + x.Phone)
如果您确实喜欢
ForEach
方法的函数方法,请在
IEnumerable
上创建扩展:

publicstaticvoidforeach(此IEnumerable集合,Action)
{
foreach(集合中的T项)
行动(项目);
}

这将比ToList()快得多。ForEach()首先,@jdv是正确的+我向他道歉。我想补充一点,如果您担心性能,请删除
ToList()
。这是创建数据的副本,只是为了在上面枚举。您现在正在对其枚举两次

相反,通常使用foreach循环:

foreach(var x in q)
    Debug.WriteLine(x.Name + x.Phone)
如果您确实喜欢
ForEach
方法的函数方法,请在
IEnumerable
上创建扩展:

publicstaticvoidforeach(此IEnumerable集合,Action)
{
foreach(集合中的T项)
行动(项目);
}

这将大大快于
ToList()。ForEach()

好的,那么对于Linq to objects方法2也同样有效吗?我想知道在Linqtosql中它是否优化了未使用的列,所以方法2是相同的。如果所有属性都是延迟加载的,那么ToList()并不意味着检索所有属性,但x.Name和x.Phone会检索,这更糟糕。。。如果属性不是延迟加载的,那么LINQ2SQL无法知道您以后将需要哪些属性:-)@tim:这可能没有太大区别,但还需要额外的工作。分配一个额外的对象,并复制两个指针。取决于可能导致明显性能差异的场景。@Sasha:我不太明白你的意思。我同意关于SQL的情况可能还有很多可以说的,但据我所知,他正在询问关于linq to objects的问题。对不起,我是在回答tim的评论。好的,那么对于linq to objects方法2同样有效吗?我想知道在Linqtosql中它是否优化了未使用的列,所以方法2是相同的。如果所有属性都是延迟加载的,那么ToList()并不意味着检索所有属性,但x.Name和x.Phone会检索,这更糟糕。。。如果属性不是延迟加载的,那么LINQ2SQL就无法知道哪些是延迟加载的