使用where / lambda和每个的区别

时间:2016-05-26 19:16:14

标签: c# where

我是C#的新手,遇到了在字典上执行过的这个功能。

 _objDictionary.Keys.Where(a => (a is fooObject)).ToList().ForEach(a => ((fooObject)a).LaunchMissles());

我的理解是,这实际上将每个作为fooObject的键放入一个列表中,然后执行每个键的LaunchMissles函数。这与为这样的每个循环使用a有何不同?

foreach(var entry in _objDictionary.Keys)
{
    if (entry is fooObject)
    {
        entry.LaunchMissles();
    }
}

编辑:响亮的意见似乎是没有功能差异。

2 个答案:

答案 0 :(得分:3)

这是滥用LINQ的好例子 - 语句没有以任何其他方式变得更具可读性或更好,但有些人只是想把LINQ放在任何地方。虽然在这种情况下,您可以通过以下方式从两个方面获得最佳效果:

foreach(var entry in _objDictionary.Keys.OfType<FooObject>())
{
    entry.LaunchMissles();    
}

请注意,在您的foreach示例中,您错过了FooObject的强制转换,以便调用LaunchMissles

答案 1 :(得分:1)

一般来说,Linq不是Voodomagic,如果你没有使用它,那么你需要编写相同的东西。 Linq只是让事情更容易编写,但它不会明智地胜过常规代码性能(如果真的相当)

在你的情况下,你的“oldschool”方法非常好,在我看来是有利的

foreach(var entry in _objDictionary.Keys)
{
    fooObject foo = entry as fooObject;
    if (foo != null)
    {
        foo .LaunchMissles();
    }
}

关于Linq-Approach:

将序列物化为List只是为了调用它上面的方法,与上面的代码相同,只是浪费了资源并使其可读性降低。

在你的例子中,它并没有产生差异,但如果源不是一个Collection(比如Dictionary.Keys),而是一个真正以懒惰方式运行的IEnumerable,那么可能会产生巨大的影响。

Lazy evalutation旨在在需要时生成项目,在实际执行ForEach之前调用Tobetween inbetween将首先收集所有项目。 虽然简单的foreach方法会获得一个项目,然后处理它,然后获得下一个项目等等。

如果你真的想使用“Linq-Foreach”,而不是使用List-Implementation,而是使用自己的扩展方法(如下面评论中提到的那样)

public static class EnumerableExtensionMethods
{ 
    public static void ForEach<T>(this IEnumerable<T> sequence, Action<T> action)
    {
        foreach(T item in sequence) 
            action(item);
    }
}

除非你把foreach-body放到不同的方法中,否则应该优先选择常规的foreach滚动

sequence.ForEach(_methodThatDoesThejob);

这是唯一一种“让我接受”的方式。