常见Linq /标准查询操作员错误/错误
对于不是来自功能编程背景的程序员,是否有错误需要避免?
人们倾向于犯的最大错误是误解了LINQ查询的懒惰和评估规则:
查询是懒惰的:它们在迭代它们之前不会被执行:
// This does nothing! No query executed!
var matches = results.Where(i => i.Foo == 42);
// Iterating them will actually do the query.
foreach (var match in matches) { ... }
此外,结果不会被缓存。 每次迭代它们时都会计算它们:
var matches = results.Where(i => i.ExpensiveOperation() == true);
// This will perform ExpensiveOperation on each element.
foreach (var match in matches) { ... }
// This will perform ExpensiveOperation on each element again!
foreach (var match in matches) { ... }
底线:知道您的查询何时执行。
对于不是来自功能编程背景的程序员,是否有错误需要避免?
好问题。 犹大指出,最大的问题是查询表达式构造一个查询,它不执行它构造的查询。
这一事实的直接后果是执行相同的查询两次可能会返回不同的结果。
这一事实的直接后果是第二次执行查询不会重新使用先前执行的结果,因为新结果可能会有所不同。
另一个重要的事实是查询最好提出问题,而不是改变状态。 尽量避免任何直接或间接导致某些东西改变其价值的查询。 例如,很多人试图做一些事情:
int number;
from s in strings let b = Int32.TryParse(s, out number) blah blah blah
这只是要求一个痛苦的世界,因为TryParse会改变查询之外的变量的值。
在这种情况下,你最好去做
int? MyParse(string s)
{
int result;
return Int32.TryParse(s, out result) ? (int?)result : (int?)null;
}
...
from s in strings let number = MyParse(s) where number != null blah blah blah...
当你面对LINQ时,你必须知道这些话题(他们是错误的重要来源):
延期执行(在SO上)
关闭(在SO-1上)
关闭(在SO-2上)
关闭(Eric Lippert的博客)
链接地址: http://www.djcxy.com/p/51097.html