使用 where/lambda 和 for each 之间的区别
Difference between using where/lambda and for each
我是 C# 的新手,在字典上发现了这个函数。
_objDictionary.Keys.Where(a => (a is fooObject)).ToList().ForEach(a => ((fooObject)a).LaunchMissles());
我的理解是,这实质上是将每个作为 fooObject 的键放入一个列表中,然后执行每个键的 LaunchMissles 函数。这与像这样使用 for each 循环有何不同?
foreach(var entry in _objDictionary.Keys)
{
if (entry is fooObject)
{
entry.LaunchMissles();
}
}
编辑:响亮的意见似乎是没有功能差异。
这是滥用 LINQ 的一个很好的例子 - 声明并没有以任何其他方式变得更具可读性或更好,但有些人只是喜欢将 LINQ 无处不在。尽管在这种情况下,您可以通过以下方式从两全其美:
foreach(var entry in _objDictionary.Keys.OfType<FooObject>())
{
entry.LaunchMissles();
}
请注意,在您的 foreach 示例中,您缺少对 FooObject
的转换以调用 LaunchMissles
.
总的来说,Linq 不是 Voodomagic,它在幕后做的事情与您不使用它时需要编写的内容相同。 Linq 只是让事情更容易编写,但它不会在性能方面击败常规代码(如果它真的等效)
在你的情况下,你的 "oldschool" 方法非常好,在我看来是有利的
foreach(var entry in _objDictionary.Keys)
{
fooObject foo = entry as fooObject;
if (foo != null)
{
foo .LaunchMissles();
}
}
关于 Linq 方法:
将序列具体化为列表只是为了在其上调用一个方法,这与上面的代码相同,只是在浪费资源并降低其可读性。
在您的示例中,它不会产生差异,但如果源不是 Collection(如 Dictionary.Keys 是)而是真正以惰性方式工作的 IEnumerable,那么就会产生巨大的影响。
惰性求值旨在在需要时产生项目,在其间调用 ToList 将首先收集所有项目,然后再实际执行 ForEach。
虽然普通的 foreach 方法会获取一个项目,然后处理它,然后获取下一个,依此类推。
如果你真的想使用 "Linq-Foreach" 而不是使用列表实现,而是使用你自己的扩展方法(就像你的问题下面的评论中提到的那样)
public static class EnumerableExtensionMethods
{
public static void ForEach<T>(this IEnumerable<T> sequence, Action<T> action)
{
foreach(T item in sequence)
action(item);
}
}
那么最好还是使用常规的 foreach 滚动,除非您将 foreach 主体放入不同的方法中
sequence.ForEach(_methodThatDoesThejob);
这是唯一的"for me acceptable"使用方法。
我是 C# 的新手,在字典上发现了这个函数。
_objDictionary.Keys.Where(a => (a is fooObject)).ToList().ForEach(a => ((fooObject)a).LaunchMissles());
我的理解是,这实质上是将每个作为 fooObject 的键放入一个列表中,然后执行每个键的 LaunchMissles 函数。这与像这样使用 for each 循环有何不同?
foreach(var entry in _objDictionary.Keys)
{
if (entry is fooObject)
{
entry.LaunchMissles();
}
}
编辑:响亮的意见似乎是没有功能差异。
这是滥用 LINQ 的一个很好的例子 - 声明并没有以任何其他方式变得更具可读性或更好,但有些人只是喜欢将 LINQ 无处不在。尽管在这种情况下,您可以通过以下方式从两全其美:
foreach(var entry in _objDictionary.Keys.OfType<FooObject>())
{
entry.LaunchMissles();
}
请注意,在您的 foreach 示例中,您缺少对 FooObject
的转换以调用 LaunchMissles
.
总的来说,Linq 不是 Voodomagic,它在幕后做的事情与您不使用它时需要编写的内容相同。 Linq 只是让事情更容易编写,但它不会在性能方面击败常规代码(如果它真的等效)
在你的情况下,你的 "oldschool" 方法非常好,在我看来是有利的
foreach(var entry in _objDictionary.Keys)
{
fooObject foo = entry as fooObject;
if (foo != null)
{
foo .LaunchMissles();
}
}
关于 Linq 方法:
将序列具体化为列表只是为了在其上调用一个方法,这与上面的代码相同,只是在浪费资源并降低其可读性。
在您的示例中,它不会产生差异,但如果源不是 Collection(如 Dictionary.Keys 是)而是真正以惰性方式工作的 IEnumerable,那么就会产生巨大的影响。
惰性求值旨在在需要时产生项目,在其间调用 ToList 将首先收集所有项目,然后再实际执行 ForEach。 虽然普通的 foreach 方法会获取一个项目,然后处理它,然后获取下一个,依此类推。
如果你真的想使用 "Linq-Foreach" 而不是使用列表实现,而是使用你自己的扩展方法(就像你的问题下面的评论中提到的那样)
public static class EnumerableExtensionMethods
{
public static void ForEach<T>(this IEnumerable<T> sequence, Action<T> action)
{
foreach(T item in sequence)
action(item);
}
}
那么最好还是使用常规的 foreach 滚动,除非您将 foreach 主体放入不同的方法中
sequence.ForEach(_methodThatDoesThejob);
这是唯一的"for me acceptable"使用方法。