如果我从列表中选择一个元素的子集,我通过选择new来获得任何东西,只获得我将使用的属性。或者编译器是否只是优化了这一点,所以我可以停止使用select new
来阻止自己,例如:
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);
答案 0 :(得分:7)
如果你正在对象进行LINQ,那就不行了。复制和分配更多临时变量时,它更可能更慢。对于LINQ to SQL,当您减少从数据库复制的数据量时,它是另一种方式。
编辑:这描述了常见的情况。对于LINQ to Objects,如果它们的检索成本很高,并且在select
语句中使用了多次,则它可能是更快的复制对象。对于LINQ to SQL,请注意不要选择实际不使用的属性。
答案 1 :(得分:2)
首先,@ jdv是正确的。 +1给他。我想补充一点,如果您担心性能,请放弃ToList()
。这是为了枚举数据而创建数据的副本。你现在两次枚举它。
相反,通常使用foreach循环:
foreach(var x in q)
Debug.WriteLine(x.Name + x.Phone)
如果您真的喜欢ForEach
方法的功能方法,请在IEnumerable<T>
上创建扩展程序:
public static void ForEach<T>(this IEnumerable<T> set, Action<T> action)
{
foreach(T item in set)
action(item);
}
这将明显快于ToList().ForEach()
答案 2 :(得分:1)
当您想要生成新类型(匿名类型)时,通常只使用“选择新建”。这不是效率问题,而是需要处理的类型问题。
答案 3 :(得分:0)
select new
创建一个匿名类型。如果您不需要它,您可能不应该使用它。
更高效率将为您提供正确的字符串比较:
where String.Equals(m.State, "AK", StringComparison.Ordinal); // or OrdinalIgnoreCase
答案 4 :(得分:0)
您绝对想要使用select new
。当你执行.ToList()时TheseGuysHaveABunchOfProperties
有很多属性(以及数据),你完全枚举了这个集合。所以你在内存中有一个列表,每个对象都有一个属性。
在select new
之前执行ToList
,列表中的对象将只包含您需要的两个属性。
如果您可以避免在ToList
之前执行ForEach
,则不会出现此问题。当然,内存使用等取决于列表的大小和TheseGuysHaveABunchOfProperties
中的属性数量。