min*_*ill 9 c# generics type-inference
我有这个代码(为了清晰起见,最小化):
interface IEither<out TL, out TR> {
}
class Left<TL, TR> : IEither<TL, TR> {
public Left(TL value) { }
}
static class Either {
public static IEither<TL, TR> Left<TL, TR> (this TL left) {
return new Left<TL, TR> (left);
}
}
Run Code Online (Sandbox Code Playgroud)
为什么我不能说:
static class Foo
{
public static IEither<string, int> Bar ()
{
//return "Hello".Left (); // Doesn't compile
return "Hello".Left<string, int> (); // Compiles
}
}
Run Code Online (Sandbox Code Playgroud)
我得到一个错误说明'string' does not contain a definition for 'Left' and no extension method 'Left' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) (CS1061).
return "Hello".Left<string, int> (); // Compiles
Run Code Online (Sandbox Code Playgroud)
没有惊喜.您明确声明了类型参数,编译器很满意.
return "Hello".Left (); // Doesn't compile
Run Code Online (Sandbox Code Playgroud)
也不足为奇,编译器无法找出TR这种情况下的内容.TL可以推断因为TL作为参数传递left但TR不能.
C#编译器没有假设您的意思,如果意图不明确,它将引发编译器错误.如果编译器认为您可能做错了什么,它会给出编译器警告.
我建议你看看部分7.5.2中C#的规范.
7.5.2类型推断
在不指定类型参数的情况下调用泛型方法时, 类型推断过程会尝试推断调用的类型参数.类型推断的存在允许使用更方便的语法来调用泛型方法,并允许程序员避免指定冗余类型信息.
[...]
类型推断作为方法调用(第7.6.5.1节)的绑定时处理的一部分发生,并发生在调用的重载决策步骤之前[...]
即解决方案在任何类型的重载解决方案完成之前发生,问题是推断你所说的方式甚至没有尝试过,并且坦率地说也不总是可行.
泛型类型参数的类型解析只能通过调用中的参数完成!在你的例子中只有一个string!它不能int从参数中推断出只有在泛型类型解析时未解析的调用上下文.