如何使用 LINQ 为每个项目调用一个方法?

how to invoke a method for each item using LINQ?

我正在尝试为列表中的每个项目调用一个方法,同时将该方法传递给列表项本身。基本上我可以用引出的方式来做,但我试图用这样一个简洁的 LINQ 语句来实现它:

var urls = html.DocumentNode.SelectNodes("//a[@href]")
             .Select(a => a.Attributes["href"].Value)
             .Where(href => !href.StartsWith("mailto:")) // skip emails, find only url links
             .ToList();
            //.ToList().ForEach(href => getWEbData(href.ToString ()));

            foreach (string s in urls) {
                getWEbData(s);
            }

I could not figure out how to get the .ForEach() in to the LINQ shorthand or if its possible.

你不能。 LINQ 函数旨在不引起副作用。 ForEach 旨在引起副作用。因此,没有 ForEach LINQ 函数。

参见 Eric Lippert 的 "foreach" vs "ForEach"

不要尝试将 foreach 与 Linq 一起使用。 Id 不添加任何值并使其更难调试。您 可以 foreach 调用中嵌入查询,如下所示:

foreach (string s in html.DocumentNode
                         .SelectNodes("//a[@href]")
                         .Select(a => a.Attributes["href"].Value)
                         .Where(href => !href.StartsWith("mailto:"))) 
{
    getWEbData(s);
}

请注意 ToList() 是不必要的(无论您在 foreach 内部还是外部进行查询)

没有 LINQ .ForEach 方法,但您可以轻松编写自己的方法:

public static class IEnumerableExtensions {
   public static void ForEach<T>(this IEnumerable<T> pEnumerable, Action<T> pAction) {
      foreach (var item in pEnumerable)
         pAction(item);
   }
}

然后

html
.DocumentNode
.SelectNodes("//a[@href]")
.Select(a => a.Attributes["href"].Value)
.Where(href => !href.StartsWith("mailto:")) // skip emails, find only url links
.ForEach(href => getWEbData(href.ToString ()));

或稍微好一些(虽然我认为href可能已经是string):

...
.Select(href => href.ToString())
.ForEach(getWEbData);

虽然,正如其他人所指出的,仅仅因为你可以并不一定意味着你应该,但这不是你的问题。

您可以将 foreach 与 Linq 一起使用,但最好有一个构造函数,即在 Select 语句中采用一个新的 class 对象并为该 class 创建一个参数化构造函数constructor 你可以做任何你想做的事情,这是最简单有效的方法之一。