Che*_*eso 15 .net c# generics type-inference c#-3.0
假设我有
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);
}
Run Code Online (Sandbox Code Playgroud)
为什么不编译?
编辑:错误是:
错误CS0411:无法从用法推断出方法'Namespace.Map <T,T2>(System.Collections.Generic.List <T>,System.Func <T,T2>)'的类型参数.尝试显式指定类型参数.
为什么我必须指定Map()函数的类型?它能否从传递中推断出来Func<T>?(就我而言,Square)
答案是否与
C#3.0泛型类型推断相同 - 将委托作为函数参数传递 ?
jas*_*son 10
从您的错误消息:
方法'
[...].Map<T,T2>(System.Collections.Generic.List<T>, System.Func<T,T2>)' 的类型参数不能从用法中推断出来.尝试显式指定类型参数.
请注意,错误消息表明它无法找出类型参数.也就是说,它无法解析其中一个类型参数T或T2.这是因为规范的§25.6.4(类型参数的推断).这是规范中涉及推断泛型类型参数的部分.
如果满足以下任何条件,则从参数中推断出任何内容(但类型推断成功):
[...]
参数是方法组.
因此,编译器无法使用委托类型Square来推断其类型T2.请注意,如果您将声明更改为
public static List<T> Map<T>(List<T> inputs, Func<T, T> f) {
return inputs.ConvertAll((x) => f(x));
}
Run Code Online (Sandbox Code Playgroud)
然后
var outputs = Map(inputs, Square);
Run Code Online (Sandbox Code Playgroud)
是合法的.在这种情况下,它已经解决了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?
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3458 次 |
| 最近记录: |