使用委托表示法访问通用列表

时间:2010-03-26 20:39:00

标签: c# .net generics

我看到有些人写道:

//wordList is List<string> 
wordList.ForEach(delegate(string word){ Console.WriteLine(word);});

而不是:

foreach(string word in wordList)
{
    Console.WriteLine(word);
}

这样做有什么好处。此外,我无法理解上面给出的Action委托语法,尽管我在C#2.0中使用了委托。基本上我无法将语法与我熟悉的代理概念联系起来。 你能帮我理解一下语法吗?这是一些简写吗?

5 个答案:

答案 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>.ForEachEric 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>个实例,则委托语法没有任何优势。