假设我有
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);
}
为什么不编译?
编辑:错误是:
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)
答案是否与
相同
C# 3.0 generic type inference - passing a delegate as a function parameter ?
最佳答案
从您的错误消息:
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 节(类型参数的推断)。这是规范中涉及推断泛型类型参数的部分。
Nothing is inferred from the argument (but type inference succeeds) if any of the following are true:
[...]
The argument is a method group.
因此,编译器无法使用 Square
的委托(delegate)类型推断 T2
的类型.请注意,如果您将声明更改为
public static List<T> Map<T>(List<T> inputs, Func<T, T> f) {
return inputs.ConvertAll((x) => f(x));
}
然后
var outputs = Map(inputs, Square);
是合法的。在这种情况下,它已经解决了 T
是int
从事实上inputs
是 List<int>
.
现在,更深层次的问题是为什么上面的规范?也就是说,为什么方法组在类型参数解析中不起作用?我认为这是因为这样的情况:
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?
}
}
关于c# - .NET:静态方法的推断泛型类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53913004/