我是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();
}
}
编辑:响亮的意见似乎是没有功能差异。
答案 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);
这是唯一一种“让我接受”的方式。