使用委托和Lambda的奇怪行为
作为在我正在开发的库中引入延迟格式化评估的一种方法,我已经定义了委托
public delegate string MessageFormatterDelegate(string message, params object[] arguments); public delegate string MessageFormatterCallback(MessageFormatterDelegate formatterDelegate);
以及下一课的内容
public static class TestClass { public static string Evaluate(MessageFormatterCallback formatterCallback) { return (formatterCallback(String.Format)); } }
但是,这表现得非常奇怪:从外部项目运行时,语句
Console.WriteLine(TestClass.Evaluate(message => message("{0},{1},{2}", 1, 2, 3)));
不编译,失败并出现错误
Error 1 Delegate 'MessageFormatterDelegate' does not take 4 arguments
而
Console.WriteLine(TestClass.Evaluate((MessageFormatterDelegate message) => message("{0},{1},{2}", 1, 2, 3)));
编译并正常工作,在控制台中打印1,2,3
。 为什么我必须在第二个lambda表达式中使用MessageFormatterDelegate
类型限定message
参数? 有没有办法来控制这种行为?
编辑:好的,我现在有一个更短的例子和一个解决方法。
第一个源文件, External.cs
:
public delegate string Callback(System.Action x);
第二个源文件Test.cs
:
class Test { static void Main() { Callback callback = action => action("hello"); } }
编译:
> csc /target:library External.cs > csc Test.cs /r:External.cs
错误:
代表’行动’不接受1个论点
解决方法:将Main
方法的主体更改为:
Callback callback = action => action.Invoke("hello");
…或在使用它的同一程序集中包含委托声明。
这对我来说肯定是个错误。 当编译器知道foo
的类型是特定的委托类型时, foo(arg)
和foo.Invoke(arg)
应该是等价的。
将邮件发送给Eric Lippert ……
更新:
该错误已在C#5中修复。再次为此带来不便,并感谢报告。
这似乎与此处描述的已知错误重复:
‘委托’System.Action’不带0个参数。’ 这是一个C#编译器错误(lambdas +两个项目)吗?
有关详细信息,请参阅我对该问题的回答
这里也有报道:
代表上的C#Parser Bug?
这个错误是我的坏事; 我为错误道歉。 我们将尝试在C#5中修复。
如果您认为您确实发现了其他错误,请告诉我们,我们将开始调查。
感谢报告,我很感激。