对LINQ和lambda表达式的限制感到好奇

时间:2017-08-31 23:32:11

标签: c# linq lambda

我知道我所要求的有其他选择,其中大多数都很简单明了。考虑一下这个一个理论问题:在这个假设的情况下,LINQ和lambda在通常的顺序命令范式中可以走多远。

所以,我必须阅读有关文件的数据。我通过IEnumerable<string>获取文件名Directory.EnumerateFiles(path : string)。我必须在每个实际上不是文件夹的文件上调用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);
}

现在明确地使用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条款。我希望将其包括在内是为了让我的意图更清晰。

解释我的意思: IEnumerable<string> 返回的 Directory.EnumerateFiles(path : string) 中的每个元素的,除了那些不满意的人 where 子句,调用 MyMethod 并传递 file 元素作为参数

是否有一种纯粹的LINQ“迷你语言”方式来表达我对计算机的意图?

2 个答案:

答案 0 :(得分:1)

如果您为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);

在您使用result 执行某项操作之前,方法实际上并未执行!为了解决这个问题,你可以在括号中包含调用,然后在结果上调用一个强制它们全部执行的方法,如Count()ToList()

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

答案 1 :(得分:1)

目前您拥有它,最好的解决方案是:

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 ...
    }
  }
}

然后你可以这样调用上面的内容:

Directory
  .EnumerateFiles(path)
  .MyMethod();

或者这个:

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