C# 4.0 中的命名参数和泛型类型推断 [英] Named arguments and generic type inference in C# 4.0

查看:17
本文介绍了C# 4.0 中的命名参数和泛型类型推断的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在编程时假设在 C# 4.0 中调用方法时,为参数提供名称不会影响结果,除非这样做是跳过"一个或多个可选参数.

I had been programming under the assumption that, when calling a method in C# 4.0, supplying names for your arguments would not affect the outcome unless in doing so you were "skipping" one or more optional parameters.

所以我有点惊讶地发现了以下行为:

So I was a bit surprised to discover the following behavior:

给定一个接受 Func 的方法,执行它并返回结果:

Given a method which takes a Func<T>, executes it and returns the result:

public static T F<T>(Func<T> f)
{
    return f();
}

还有一个方法可以看到上面的方法:

And another method from which the above method is visible:

static void Main()
{
    string s;

调用 F(没有命名参数)编译没有任何问题:

calling F (without named arguments) compiles without any issues:

    s = F<string>(() => "hello world"); // with explicit type argument <string>
    s = F(() => "hello world"); // with type inference

当使用命名参数时...

And when using a named argument...

    s = F<string>(f: () => "hello world");

...使用显式类型参数的上述代码行仍然可以正常编译.也许并不奇怪,如果您安装了 ReSharper,它会提示类型参数规范是多余的".

... the above line of code using the explicit type argument still compiles without issues. And maybe not too surprisingly, if you have ReSharper installed it will suggest that the "Type argument specification is redundant".

但是,当删除类型参数时...

However, when removing the type argument...

    s = F(f: () => "hello world");

C#编译器会报这个错误:

the C# compiler will report this error:

无法从用法推断出方法Program.F(System.Func)"的类型参数.尝试明确指定类型参数.

The type arguments for method 'Program.F(System.Func)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

对于命名参数和类型推断之间的这种交互是否有合乎逻辑的解释?

Is there a logical explanation for this interaction between named arguments and type inference?

此行为是否记录在语言规范中的某处?

Is this behavior documented somewhere in the language specification?

我知道我完全没有必要命名参数.但是,我在一个更复杂的场景中发现了这种行为,我认为在我的方法调用中为内部文档目的命名参数可能是有意义的.我不是在问如何解决这个问题.我正在尝试理解该语言的一些细节.

I understand that it is not necessary at all for me to name the argument. However, I discovered this behavior in a much more complex scenario where I thought it might make sense to name the arguments in my method call for internal documentation purposes. I am not asking how to work around this issue. I am trying to understand some of the finer points of the language.

为了让事情更有趣,我发现以下所有编译都没有问题:

To make things more interesting I discovered that the following all compiles without issues:

    Func<string> func = () => "hello world";
    s = F<string>(func);
    s = F(func);
    s = F<string>(f: func);
    s = F(f: func);
}

顺便说一下,我观察到了非静态方法的相同行为.我只是选择使用静态方法来使这里的示例更短一些.

By the way I have observed the same behavior with non-static methods. I just chose to use static methods to make the example here a bit shorter.

推荐答案

推理不是在编译中的许多嵌套级别都有效的东西.这是一种基于提供的参数的猜测.我觉得编译器作者没有考虑推断逻辑和命名参数.如果考虑抽象语法树,即使逻辑相同,但两者F(()=>"xyz")和F(f:()=>"xyz")从编译器的角度来看是不同的抽象语法树.

Inference is not something that will work at many nested levels in compilation. It is kind of a guess based on arguments supplied. I feel the compiler writers did not consider inferring logic along with named parameter. If you consider abstract syntax tree, Even though the logic is same, but both F(()=>"xyz") And F(f:()=>"xyz") Are different abstract syntax trees from compiler's perspective.

我觉得这只是编译器设计者遗漏的一条规则,甚至编译器本身也是一个具有大量规则的程序.一个规则匹配第一种情况,但没有规则匹配第二种情况.它在概念上可能是正确的,但编译器只是一个程序,所有规则都是人工编码的.

I feel it's just a rule missed by compiler designer where even the compiler itself is a program with huge set of rules. One rule matches first case but no rule matches second one. It may be conceptually right but compiler is just a program and all rules are human coded.

好吧,我想正如其他人已经确定的那样,这是一个错误,应该报告给 Microsoft !

Ok, I guess as others have determined, its a bug and should be reported to Microsoft !!

这篇关于C# 4.0 中的命名参数和泛型类型推断的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆