Ole*_*ema 52 c# linq ienumerable list c#-3.0
我注意到在编写LINQ-y代码时,.ForEach()是一个很好用的习惯用法.例如,这是一段代码,它接受以下输入,并产生这些输出:
{ "One" } => "One"
{ "One", "Two" } => "One, Two"
{ "One", "Two", "Three", "Four" } => "One, Two, Three and Four";
Run Code Online (Sandbox Code Playgroud)
和代码:
private string InsertCommasAttempt(IEnumerable<string> words)
{
List<string> wordList = words.ToList();
StringBuilder sb = new StringBuilder();
var wordsAndSeparators = wordList.Select((string word, int pos) =>
{
if (pos == 0) return new { Word = word, Leading = string.Empty };
if (pos == wordList.Count - 1) return new { Word = word, Leading = " and " };
return new { Word = word, Leading = ", " };
});
wordsAndSeparators.ToList().ForEach(v => sb.Append(v.Leading).Append(v.Word));
return sb.ToString();
}
Run Code Online (Sandbox Code Playgroud)
请注意第二行到最后一行的.ForEach()之前插入的.ToList().
为什么.ForEach()不能作为IEnumerable的扩展方法?有了这样的例子,它看起来很奇怪.
提前致谢,
戴夫
Jus*_* R. 39
根据Eric Lippert的说法,这主要是出于哲学原因.你应该阅读整篇文章,但就我而言,这里是要点:
出于两个原因,我在哲学上反对提供这样的方法.
第一个原因是这样做违反了所有其他序列运算符所基于的函数式编程原则.显然,调用此方法的唯一目的是引起副作用.
表达式的目的是计算一个值,而不是引起副作用.声明的目的是产生副作用.这个东西的调用站点看起来很像一个表达式(但是,诚然,由于该方法是void返回的,因此表达式只能用于"语句表达式"上下文.)
对我来说,制作唯一一个仅对其副作用有用的序列运算符并不合适.
第二个原因是,这样做会增加语言的新代表性能力.
Sam*_*uel 38
因为ForEach(Action)存在之前IEnumerable<T>存在.
由于没有添加其他扩展方法,可以假设C#设计者认为它是一个糟糕的设计并且更喜欢foreach构造.
如果你想要你可以创建自己的扩展方法,它不会覆盖a的那个,List<T>但它适用于任何其他实现的类IEnumerable<T>.
public static class IEnumerableExtensions
{
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
foreach (T item in source)
action(item);
}
}
Run Code Online (Sandbox Code Playgroud)
因为ForEach()在IEnumerable上只是每个循环的正常,如下所示:
for each T item in MyEnumerable
{
// Action<T> goes here
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
25996 次 |
| 最近记录: |