C# 对LINQ和lambda表达式的极限感到好奇

C# 对LINQ和lambda表达式的极限感到好奇,c#,linq,lambda,C#,Linq,Lambda,我知道除了我的要求,还有其他的选择,大多数都是简单明了的。认为这是一个理论问题:在这个假设的情况下,LINQ和LAMBDA可以把我从通常的顺序命令范式中走多远。 所以,我必须读取有关文件的数据。我通过执行Directory.EnumerateFilePath:string获得文件名的IEnumerable。我必须对实际上不是文件夹的每个文件调用MyMethod 首先,我将展示被广泛接受的备选方案,我认为这些将是最佳选择: 一个完全必要的解决方案: var files = Directory.En

我知道除了我的要求,还有其他的选择,大多数都是简单明了的。认为这是一个理论问题:在这个假设的情况下,LINQ和LAMBDA可以把我从通常的顺序命令范式中走多远。

所以,我必须读取有关文件的数据。我通过执行Directory.EnumerateFilePath:string获得文件名的IEnumerable。我必须对实际上不是文件夹的每个文件调用MyMethod

首先,我将展示被广泛接受的备选方案,我认为这些将是最佳选择:

一个完全必要的解决方案:

var files = Directory.EnumerateFiles(path);
foreach(f in files)
{
    if(!Directory.Exists(f))
        MyMethod(f);
}
var seq = from file in Directory.EnumerateFiles(path) 
          where !Directory.Exists(file) 
          select file;

foreach(string str in seq)
{
    MyMethod(str);
}
两步解决方案:

var files = Directory.EnumerateFiles(path);
foreach(f in files)
{
    if(!Directory.Exists(f))
        MyMethod(f);
}
var seq = from file in Directory.EnumerateFiles(path) 
          where !Directory.Exists(file) 
          select file;

foreach(string str in seq)
{
    MyMethod(str);
}
现在,使用LINQ的扩展方法显式地链接整个内容,这是我从实际将行完全转换为声明性范例中所能得到的最接近的结果:

Directory.EnumerateDirectories(path)
         .Where(f => !Directory.Exists(f))
         .ToList()
         .ForEach(f => MyMethod(f));
现在,我甚至不能开始构造一些在C形式语法中可以接受的东西,但我在想象,如果我能做一些类似于下面这行的事情,我的精神会是怎样的

from file in Directory.EnumerateFiles(path) 
where !Directory.Exists(file) 
do MyMethod(file);
我知道do在这里特别不合适,因为它甚至不是lambda条款。我希望把它包括在内,是为了让我的意图更清楚

解释我的意思:对于Directory.EnumerateFilePath:string返回的IEnumerable中的每个元素(不满足where子句的元素除外),调用MyMethod并将file元素作为参数传递

有没有一种纯LINQ迷你语言的方式可以向计算机展示我的意图?

如果给MyMethod一个返回值,您就可以这样做。否则,select不会返回任何内容:

static bool MyMethod(string input)
{
    Console.WriteLine(input);
    return true;
}
那么您应该能够执行以下操作,但仍然存在一个问题:

var result = from file in Directory.EnumerateFiles(path) 
    where !Directory.Exists(file) select MyMethod(file);
在您对结果执行某些操作之前,该方法实际上不会执行!要解决这个问题,您可以将调用括在括号中,然后对结果调用一个方法,强制所有结果执行,如Count或ToList:


目前,最好的解决方案是:

foreach(var file in Directory.EnumerateFiles(path))
{
  MyMethod(file);
}
但是,如果您想继续往下看,可以这样编写MyMethod:

public static class MyExensions
{
  public static void MyMethod(this IEnumerable<string> files)
  {
    foreach(var file in files)
    {
      ... Do stuff with file ...
    }
  }
}
或者这个:

(from file in Directory.EnumerateFiles(path)).MyMethod();

当您传递指向文件的路径时,Directory.Exists会做什么?您不应该这样做。没有LINQ子句接受返回void的语句或表达式。当然,您可以在DoAction a{a;return 0;}中编写一个helper方法,然后选择Do=>MyMethodfile,这在技术上符合模式-LINQ查询不禁止产生副作用,这只是一个糟糕的想法。使用foreach,这就是它的用途。查询查询事物,它们不起作用。你是说C形式语法是LINQ吗?i、 e.我同意@Jeroenmoster的说法。当我第一次尝试使用LINQ时,我得到的一般建议是,在使一些foreach类型的查找和查询整洁高效方面,LINQ占有一席之地。但我得到的最大警告是,比起聪明的代码,我更喜欢可读的代码。仅供参考,EnumerateFile将只返回文件,而EnumerateDirectory将只返回目录,所以!目录。是否存在检查可以删除。。。