使用委托和Lambda的奇怪行为

Dot*_*ent 15 c# lambda .net-3.5

作为在我正在开发的库中引入延迟格式化评估的一种方法,我已经定义了委托

public delegate string MessageFormatterDelegate(string message, params object[] arguments);
public delegate string MessageFormatterCallback(MessageFormatterDelegate formatterDelegate);
Run Code Online (Sandbox Code Playgroud)

以及下一课的内容

public static class TestClass
{
    public static string Evaluate(MessageFormatterCallback formatterCallback)
    {
        return (formatterCallback(String.Format));
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,这表现得非常奇怪:从外部项目运行时,语句

Console.WriteLine(TestClass.Evaluate(message => message("{0},{1},{2}", 1, 2, 3)));
Run Code Online (Sandbox Code Playgroud)

没有编译,与错误而失败

Error   1   Delegate 'MessageFormatterDelegate' does not take 4 arguments
Run Code Online (Sandbox Code Playgroud)

Console.WriteLine(TestClass.Evaluate((MessageFormatterDelegate message) => message("{0},{1},{2}", 1, 2, 3)));
Run Code Online (Sandbox Code Playgroud)

编译和工作没有问题,1,2,3在控制台中打印.为什么我必须message使用MessageFormatterDelegate第二个lambda表达式中的类型限定参数?有没有办法来控制这种行为?

Eri*_*ert 11

更新:

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


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

'委托'System.Action'不带0个参数.' 这是一个C#编译器错误(lambdas +两个项目)吗?

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

这里也有报道:

代表上的C#Parser Bug?

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

如果您认为自己确实发现了其他错误,请告诉我们,我们将开始调查.

感谢报告,我很感激.


Jon*_*eet 7

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

第一个源文件,External.cs:

public delegate string Callback(System.Action<string> x);
Run Code Online (Sandbox Code Playgroud)

第二个源文件,Test.cs:

class Test
{
    static void Main()
    {
        Callback callback = action => action("hello");
    }
}
Run Code Online (Sandbox Code Playgroud)

编译:

> csc /target:library External.cs
> csc Test.cs /r:External.cs
Run Code Online (Sandbox Code Playgroud)

错误:

代表'行动'不带1个参数

解决方法:将Main方法的主体更改为:

Callback callback = action => action.Invoke("hello");
Run Code Online (Sandbox Code Playgroud)

...或在使用它的同一程序集中包含委托声明.

这对我来说绝对是一个错误.当编译器知道类型foo是特定的委托类型时,那么foo(arg)foo.Invoke(arg)应该是等价的.

邮寄Eric Lippert ......