我从一本 C# 书中得到了这段代码:
int minSize = 10000;
var bigFiles = from file in GetAllFilesInDirectory(@"c:\")
where new FileInfo(file).Length > minSize
select file;
var filesOver10k = bigFiles.ToArray();
minSize = 100000;
var filesOver100k = bigFiles.ToArray();
minSize = 1000000;
var filesOver1MB = bigFiles.ToArray();
minSize = 10000000;
var filesOver10MB = bigFiles.ToArray();
作者说它会在每次调用 ToArray() 时重新评估查询。我想做类似的事情。我需要查询字母表中的每个字母在一本书中使用了多少次;目前我正在使用这样的东西:
string alphabet="abcdefghijklmnopqrstuvwxyz";
foreach(char a in alphabet)
{
var stat_letter=book2.book.Sum(b=>b.chapter.Sum(l=>l.line.Sum(w=>w.word.ToLower().Count(c=>c.Equals(a)))));
Console.WriteLine(a + ":" + stat_letter.ToString() );
}
我得到的输出:
a: 31278
b: 6263
c: 14561
[...]
我想将其更改为更像书中的示例:
char q = 'a';
var stat_letter = book2.book.Sum(b=>b.chapter.Sum(l=>l.line.Sum(w=>w.word.ToLower().Count(c=>c.Equals(q)))));
string alphabet="abcdefghijklmnopqrstuvwxyz";
foreach(char a in alphabet)
{
q=a;
Console.WriteLine(q + ":" + stat_letter.ToString() );
}
我从中得到的输出:
a: 31278
b: 31278
c: 31278
[...]
在这种情况下,查询似乎没有重新评估。有什么办法强制吗?其实我的动机是检查它是否会加快程序执行速度,所以如果你认为它不会,那也是我想知道的......
最佳答案
Sum
返回一个 int
(使用您选择的重载)而不是一个 IEnumerable
。这意味着它会立即求值,因为它需要 int
。 int
的值不能延迟。
虽然有几种方法可以重新构建代码以延迟执行,但我更愿意做的是创建一个方法(或 lambda,实际上是相同的概念),根据您的输入计算您想要的值,而不是改变查询所依赖的变量。
Func<char, int> computeLetterCount = letter => book2.book.Sum(
b=>b.chapter.Sum(
l=>l.line.Sum(
w=>w.word.ToLower().Count(c=>c.Equals(letter)))));
你现在可以写:
foreach(char a in alphabet)
{
Console.WriteLine(a + ":" + computeLetterCount(a) );
}
关于c# - 强制LINQ再次执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23435474/