使用LINQ替换foreach循环

13

我试图替换代码

foreach (var discovery in mpwrapper.parser.Discoveries)
{
   solution.AddFile("Discoveries", discovery.DisplayStringName + ".mpx", discovery);
}

使用以下linq表达式

mpwrapper.parser.Discoveries.Select(
                    s => solution.AddFile("Discoveries", s.DisplayStringName + ".mpx", s));

但是出现了错误

无法从使用中推断方法'System.Linq.Enumerable.Select(System.Collections.Generic.IEnumerable,System.Func)'的类型参数。尝试显式指定类型参数。

如何将此foreach循环转换为在我的IEnumerable集合中对每个对象执行方法的linq查询?


жҲ‘зҢңжөӢдҪ зҡ„solution.AddFileж–№жі•жІЎжңүиҝ”еӣһд»»дҪ•еҶ…е®№ - жҳҜиҝҷж ·еҗ—пјҹ - Dan Puzey
1
选择使用具有副作用的代码来执行是不合适的。只需使用foreach或者List<T>.ForEach()方法,该方法预期具有副作用(即在方法外部进行状态更改)。 - Gert Arnold
4
顺便说一下,仅仅为了改变foreach循环而使用Linq是我在.NET中知道的最常见的使代码更难理解和调试的技巧之一。 - Daniel Daranas
7个回答

19

我觉得你需要的是 ForEach 方法 ;)

mpwrapper.parser.Discoveries.ToList().ForEach(s => { solution.AddFile("Discoveries", s.DisplayStringName + ".mpx", s); });

18
在我看来,最好还是坚持使用 foreach,这样更清晰易懂。参见 http://blogs.msdn.com/b/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx。请注意,在不知道 Discoveries 的类型的情况下,我们不知道这是否会编译通过... - Jon Skeet
他说这是一个IEnumerable对象,所以应该可以编译通过。 我回答了他的问题,不管它是否更好。但你是对的,使用foreach可能会更好。 - dotixx
1
不,IEnumerable<T> 上没有 ForEach 扩展方法。当然你可以自己写一个,但我建议不要这样做。 - Jon Skeet
我添加了我忘记的ToList()调用;P - dotixx
Linq的foreach与普通的foreach相比,在列表上会增加性能吗? - Kurkula

6
问题在于Select需要返回一个值,而Linq并不是为了改变集合而设计的。把Select看作是集合上的转换,而不是每个项的状态更改。也许foreach循环在这里是最好的解决方案。

1
LINQ也适用于可变集合,但它不是设计用于自身改变它们。 - Jon Skeet

4
LINQ代表语言集成查询...但实际上你并没有进行任何查询。
如果mpwrapper.parser.Discoveries是一个List<T>,你可以使用ForEach方法;或者,如果它是一个IEnumerable,你也可以添加一个ForEach扩展方法...但这只是一个小的美学改变,与LINQ无关。

2

我在使用.All方法时有一个小技巧。它只需要返回布尔值并且呈现非常整洁。我在其中包含了一个嵌入的linq示例。

configurations.All(c =>
{
    var gcx = globalConfigurations.FirstOrDefault(gc =>
        gc.Type == c.Type && configurationGuids.Any(cGuid => gc.Guid == cGuid)
    );
    return true;
});

1

试试这个:

mpwrapper.parser.Discoveries.ToList()
    .ForEach(s =>
        solution.AddFile("Discoveries", s.DisplayStringName + ".mpx", s));

1
List<T>.ForEach 方法可以解决问题。
然而,这个方法在 IEnumerable<T> 上不存在。

0
如果Discoveries是一个列表,那么可以这样做。
mpwrapper.parser.Discoveries.ForEach(discovery => solution.AddFile("Discoveries", discovery .DisplayStringName + ".mpx", discovery);

如果不是,先转换成列表 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接