使用委托和Lambda的奇怪行为

时间:2012-02-03 11:46:41

标签: c# .net-3.5 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表达式中使用message类型限定MessageFormatterDelegate参数?有没有办法来解决这种行为?

2 个答案:

答案 0 :(得分:11)

UPDATE:

该错误已在C#5修复。再次为此带来不便,并感谢报告。


这似乎与此处描述的已知错误重复:

'Delegate 'System.Action' does not take 0 arguments.' Is this a C# compiler bug (lambdas + two projects)?

有关详细信息,请参阅我对该问题的回答。

此处也有报道:

C# Parser Bug on delegate?

这个错误是我的坏事;我为错误道歉。我们将尝试在C#5中修复。

如果您认为自己确实发现了不同的错误,请告诉我们,我们会开始调查。

感谢报告,我很感激。

答案 1 :(得分:7)

编辑:好的,我现在有一个更短的例子一个解决方法。

第一个源文件External.cs

public delegate string Callback(System.Action<string> 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 ......