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

时间:2012-11-13 14:13:33

标签: c# visual-studio-2010 c#-4.0 type-inference

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

public static S Foo<S, T>(this S s) where S : IEnumerable<T>
{
    return s;
}

现在如果我打电话

"".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?)

我完全不了解引擎盖下发生了什么。令人讨厌的部分是 intellisense列出了Foo s IEnumberable<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.

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

更多

假设我有:

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

如果我打电话:

"".Foo(1);

类型推断非常明智,告诉我 Foo应该返回IEnumerable<int>string不是全部!

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

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

"".Foo('l');

我只是想知道为什么在所有字符串为T之后,第一个示例中char不能被推断为IEnumberable<char>


编辑:

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

换句话说:

public static S Foo<S, T>(this S s)
{
    return s;
}

在所有Foo上提供object

public static S Foo<S, T>(this S s) where S : IEnumerable<T>
{
    return s;
}

在所有Foo上提供IEnumerable<T>,因为它知道 SIEnumerable<T>。所以我认为C#甚至会推断出T的类型!感谢大家! ;)

1 个答案:

答案 0 :(得分:9)

类型推理引擎不够智能。

C#类型推断仅查看方法签名 Generic constraints are not part of the signature

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