我看到有些人写道:
//wordList is List<string>
wordList.ForEach(delegate(string word){ Console.WriteLine(word);});
而不是:
foreach(string word in wordList)
{
Console.WriteLine(word);
}
这样做有什么好处。此外,我无法理解上面给出的Action委托语法,尽管我在C#2.0中使用了委托。基本上我无法将语法与我熟悉的代理概念联系起来。 你能帮我理解一下语法吗?这是一些简写吗?
答案 0 :(得分:2)
Eric Lippert已blogged about exactly this topic。
你一定要阅读这篇文章,但是为了简要总结一下他的一个要点,他建议:表达的唯一目的是产生副作用,应该是陈述。这里的前提是,为foreach
循环创建功能扩展会增加语言的表达能力,并且在某些情况下可能会有害。
引用他的文章:
当我们提供两个微妙的不同 我们做同样事情的方法 我们在行业中产生混乱 让人们更难阅读每一个 其他的代码,等等。有时候 有两个不同的好处 一个文本表示 操作(如查询表达式 与他们的基础方法调用 形式,或+与String.Concat)是如此 这是值得的 混乱。但令人信服的好处 查询表达式是他们的 可读性;这种新的形式 “foreach”肯定不复存在 比“正常”形式可读并且是 可以说更糟糕。
答案 1 :(得分:2)
.NET 2中提供了delegate() {...}
语法。它实质上在包含类的类中创建了一个(匿名)方法,该方法具有委托的内容。所以,上面的语法等同于
private void actionImpl(string word) {
Console.WriteLine(word);
}
wordList.ForEach(new Action<string>(actionImpl));
关于List<T>.ForEach
,Eric Lippert has blogged about this。当一个动作没有副作用时,这是有用的。是一个非常简单的单线。使用隐式委托创建&amp;方法组,您可以将代码示例缩小为
wordList.ForEach(Console.WriteLine);
Console.WriteLine(string s)
与Action<string>
委托签名匹配。在这个特定的实例中,这比使用显式foreach
循环更简单,并且(我认为)更清晰。
答案 2 :(得分:0)
委托语法是使用匿名函数。
它允许您定义内联函数以帮助澄清您的代码。 你可以在msdn上找到更详细的解释: http://msdn.microsoft.com/en-us/library/bb882516.aspx
答案 3 :(得分:0)
第一种是更多功能性的编程风格。它留下了每个单词如何打印到底层系统的实现细节。虽然可能不在您的示例中,但它确实让系统优化(并行化是一个关键的)关于实现细节,而第二个没有。
在第一个示例中,您告诉系统“对每个项目执行此操作”。在第二个例子中,您说“循环遍历此集合并执行此操作。”
本书Real World Functional Programming讨论了两种风格之间的区别。
答案 4 :(得分:0)
如果您没有在方法之间传递Action<string>
个实例,则委托语法没有任何优势。