虽然智能感知列表找不到定义吗?

naw*_*fal 5 c# type-inference visual-studio-2010 c#-4.0

我在Visual Studio 10中遇到了一个奇怪的错误(现在也是11).我有一个扩展方法

public static S Foo<S, T>(this S s) where S : IEnumerable<T>
{
    return s;
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我打电话

"".Foo(); // => 'string' does not contain a definition for 'Foo' and no extension method 'Foo' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?)
Run Code Online (Sandbox Code Playgroud)

我根本不了解引擎盖下发生了什么.恼人的是,在智能感知列出FooIEnumberable<T>小号.最好它应该给出一个type can't be inferred error.

如果我这样称呼它:

Extension.Foo(""); // => The type arguments for method 'Extension.Foo<S,T>(S)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
Run Code Online (Sandbox Code Playgroud)

为什么不能在上述情况下推断出类型?

更多:

假设我有:

public static S Foo<S, T>(this S s, T t) where S : IEnumerable<T>
{
    return s;
}
Run Code Online (Sandbox Code Playgroud)

如果我打电话:

"".Foo(1);
Run Code Online (Sandbox Code Playgroud)

类型推断是如此聪明,告诉我Foo应该返回IEnumerable<int>,string并不是全部!

因此,如果编译器可以知道Foo期望将char作为第一个参数,那么为什么我的第一个例子不能编译?换句话说,为什么在第一个例子中,编译器知道T在这种情况下是char?

正如预期的那样,这适用于第二个例子:

"".Foo('l');
Run Code Online (Sandbox Code Playgroud)

我只是想知道为什么不能在第一个例子中T推断char,毕竟字符串是IEnumberable<char>.


编辑:

我从SLaks那里得到了答案.但是C#不这样做(类型推断)是很奇怪的,因为编译器在暴露可用的方法来操作对象时也会考虑通用约束.

换一种说法:

public static S Foo<S, T>(this S s)
{
    return s;
}
Run Code Online (Sandbox Code Playgroud)

Foo适用于所有object秒.

public static S Foo<S, T>(this S s) where S : IEnumerable<T>
{
    return s;
}
Run Code Online (Sandbox Code Playgroud)

Foo适用于所有IEnumerable<T>S ^,因为它知道 SIEnumerable<T>.所以我认为C#甚至会推断出它的类型T!感谢大家!;)

SLa*_*aks 9

类型推理引擎不够智能.

C#类型推断仅查看方法签名.
通用约束不是签名的一部分.

由于T未直接在签名中使用,编译器不会推断它.

  • 具体设置泛型类型会起作用:`"".Foo <string,char>();` (4认同)