.NET:推断静态方法的泛型类型 [英] .NET: Inferred generic types on static methods
问题描述
假设我有
public static List<T2> Map<T,T2>(List<T> inputs, Func<T, T2> f)
{
return inputs.ConvertAll((x) => f(x));
}
private int Square(int x) { return x*x; }
public void Run()
{
var inputs = new List<Int32>(new int[]{2,4,8,16,32,64,128,256,512,1024,2048});
// this does not compile
var outputs = Map(inputs, Square);
// this is fine
var outputs2 = Map<Int32,Int32>(inputs, Square);
// this is also fine (thanks, Jason)
var outputs2 = Map<Int32,Int32>(inputs, (x)=>x*x);
// also fine
var outputs2 = Map(inputs, (x)=>x*x);
}
为什么不编译?
编辑:错误是:
错误CS0411:无法从用法中推断出方法'Namespace.Map< T,T2>(System.Collections.Generic.List< T,System.Func< T,T2>))的类型参数。尝试显式指定类型参数。
error CS0411: The type arguments for method 'Namespace.Map<T,T2>(System.Collections.Generic.List<T>, System.Func<T,T2>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
为什么必须指定Map()函数的类型?它不能从传递的 Func< T>
推断出来吗? (在我的情况下为Square)
Why do I have to specify the type of the Map() function? Can it not infer this from the passed Func<T>
? (in my case, Square)
推荐答案
从您的错误消息中:
方法'
[...]。Map< T,T2>(System.Collections.Generic.List< T> ;, System.Func< ; T,T2>)
'不能从用法中推断出来。尝试显式指定类型参数。
The type arguments for method '
[...].Map<T,T2>(System.Collections.Generic.List<T>, System.Func<T,T2>)
' cannot be inferred from the usage. Try specifying the type arguments explicitly.
请注意,错误消息指出无法确定类型参数。也就是说,它无法解析类型参数 T
或 T2
之一。这是因为规范的第25.6.4节(类型参数的推断)。这是规范中涉及推断泛型类型参数的部分。
Note that the error message says that it can not figure out the type arguments. That is, it is having trouble resolving one of the type parameters T
or T2
. This is because of §25.6.4 (Inference of type arguments) of the specification. This is the part of the specification the deals with inferring generic type parameters.
如果没有从参数中推断出任何内容(但类型推断成功),如果满足以下任何条件:
Nothing is inferred from the argument (but type inference succeeds) if any of the following are true:
[...]
该参数是方法组。
因此,编译器无法使用 Square
的委托类型来推断 T2
的类型。请注意,如果将声明更改为
Thus, the compiler is not able to use the delegate type of Square
to infer the type of T2
. Note that if you change the declaration to
public static List<T> Map<T>(List<T> inputs, Func<T, T> f) {
return inputs.ConvertAll((x) => f(x));
}
然后
var outputs = Map(inputs, Square);
是合法的。在这种情况下,它已经根据 inputs <<来解决
T
是 int
的问题。 / code>是 List< int>
。
is legal. In this case, it has already resolved that T
is int
from the fact that inputs
is a List<int>
.
现在,更深层的问题是为什么高于规格?也就是说,为什么方法组在类型参数解析中不起作用?我认为是因为这样的情况:
Now, the deeper question is why is the above the specification? That is, why don't method groups play a role in type parameter resolution? I think it's because of cases like this:
class Program {
public static T M<T>(Func<T, T> f) {
return default(T);
}
public static int F(int i) {
return i;
}
public static float F(float f) {
return f;
}
static void Main(string[] args) {
M(F); // which F am I?
}
}
这篇关于.NET:推断静态方法的泛型类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!