我一直在以这样的假设下进行编程:当在C# 4.0中调用方法时,除非你“跳过”了一个或多个可选参数,否则为参数命名不会影响结果。
所以当我发现以下行为时有点惊讶:
给定一个接受 Func<T>
, 执行它并返回结果的方法:
public static T F<T>(Func<T> f)
{
return f();
}
以下是另一种可见以上方法的方法:
static void Main()
{
string s;
调用F(不使用命名参数)编译时没有任何问题:
s = F<string>(() => "hello world"); // with explicit type argument <string>
s = F(() => "hello world"); // with type inference
当使用命名参数时...
s = F<string>(f: () => "hello world");
使用显示类型参数的上述代码行仍然可以编译而不会出现问题。也许并不奇怪,如果您安装了ReSharper,它会建议"类型参数规范是多余的"。
但是,当删除类型参数时......
s = F(f: () => "hello world");
C#编译器会报告以下错误:
无法从使用中推断方法“Program.F(System.Func)”的类型参数。尝试显式指定类型参数。
命名参数和类型推断之间有逻辑上的解释吗?
这种行为是否在语言规范中有所说明?
我知道根本没必要给参数命名。然而,在更复杂的场景下,我发现在方法调用中为了内部文档目的而命名参数可能是有意义的。我不是在询问如何解决此问题。我试图理解该语言的一些细节。
为了使事情更有趣,我发现以下所有内容都可以编译而没有问题:
Func<string> func = () => "hello world";
s = F<string>(func);
s = F(func);
s = F<string>(f: func);
s = F(f: func);
}
顺便说一下,我发现非静态方法也有相同的行为。我只是选择使用静态方法来使这个例子更短。