Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 泛型、重载解析和委托(抱歉,找不到更好的标题)_C#_Generics_Compiler Construction_Overload Resolution - Fatal编程技术网

C# 泛型、重载解析和委托(抱歉,找不到更好的标题)

C# 泛型、重载解析和委托(抱歉,找不到更好的标题),c#,generics,compiler-construction,overload-resolution,C#,Generics,Compiler Construction,Overload Resolution,可能重复: 我注意到泛型有一个非常奇怪的重载解决问题 考虑以下方法: static void Foo<TSource>(TSource element, Func<TSource, int> selector) { "int".Dump(); } static void Foo<TSource>(TSource element, Func<TSource, double> selector) { "double".Dump();

可能重复:

我注意到泛型有一个非常奇怪的重载解决问题

考虑以下方法:

static void Foo<TSource>(TSource element, Func<TSource, int> selector)
{
    "int".Dump();
}

static void Foo<TSource>(TSource element, Func<TSource, double> selector)
{
    "double".Dump();
}

static T Identity<T>(T value)
{
    return value;
}
但是如果我将
x=>x
替换为
Identity
,编译器将无法决定2个
Foo
重载:

Foo(42, Identity);
// The call is ambiguous between the following methods or properties:
// 'UserQuery.Foo<int>(int, System.Func<int,int>)' and
// 'UserQuery.Foo<int>(int, System.Func<int,double>)'
这里怎么会有歧义呢?就我所知,需要
Func
的重载不可能成为候选。我猜说明一定在说明书的某个地方,但我找不到相关的部分。。。或者它可能是编译器中的一个bug,但我想这不太可能

请注意,如果我显式创建委托,它确实可以工作:

Foo(42, new Func<int, int>(Identity)); // prints "int"
Foo(42,新函数(标识));//打印“int”

有人能解释一下这是怎么回事吗?另外,为什么它可以与lambda一起工作,而不能与方法组一起工作?

不是因为返回类型不是方法签名的一部分吗


当编译器试图决定需要哪一个
Foo
重载时,不会考虑
Identity
方法的参数类型和返回类型保证相同这一事实。如果不考虑返回类型,那么
Identity
可以同样地转换为
Func
Func
Func
,我认为LukeH是正确的。但是,要回答您问题的第二点:lambda的代表已经填写了所有类型(例如,如果
TSource
int
,则始终是
Func
),这就是为什么在这种情况下没有歧义。它不像函数签名那样忽略返回类型。

耐心地等待Eric Lippert发布答案。在C#3下会发生什么?我怀疑这可能与泛型中的类型差异有关。@Anon,我没有尝试使用C#3,但我认为这与差异无关,因为差异不适用于值types@Ben沃格特,我同意,这是个骗局。。。我不知道该找什么;)我对重复的问题发表了新的分析。我想就是这样。让我们看看Eric会怎么说!说得好,我忘了返回类型不是签名的一部分…是的,我认为这是正确的解释…绝对不是。lambda是高度上下文敏感的。事实上,lambda版本是不明确的@Ben Voigt,我不明白你的意思。。。这段代码应该说明什么?它适用于lambda,因此它必须是明确的……它表明您提供的lambda与“double”函数完全可用。
Foo<int>(42, Identity<int>); // The call is ambiguous...
Foo(42, new Func<int, int>(Identity)); // prints "int"