【发布时间】:2011-09-26 10:26:40
【问题描述】:
我的编程假设是,在 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);
}
顺便说一句,我观察到非静态方法的行为相同。我只是选择使用静态方法来使这里的示例更短一些。
【问题讨论】:
-
听起来像是 Resharper 的问题...
-
哦,埃里克! Eeeeeeeeeeeeric Lippert,请过来解释一下!
-
我们应该引入一个“for:eric”标签吗?
-
作为参考,我尝试使用安装在 Ubuntu 上的 Mono 2.6.7 C# 编译器来编译您的示例。它编译问题行,没有警告或错误。
标签: c# generics c#-4.0 compiler-errors type-inference