Why does the C# compiler not infer the fact that FooExt.Multiply()
satisfies the signature of Functions.Apply()
? I have to specify a separate delegate variable of type Func<Foo,int,int>
for the code to work ... but it seems like 开发者_如何转开发type inference should handle this. Am I wrong? And, if so, why?
EDIT: The compilation error received is:
The type arguments for method
FirstClassFunctions.Functions.Apply<T1,T2,TR>(T1, System.Func<T1,T2,TR>, T2)'
cannot be inferred from the usage. Try specifying the type arguments explicitly
namespace FirstClassFunctions {
public class Foo {
public int Value { get; set; }
public int Multiply(int j) {
return Value*j;
}
}
public static class FooExt {
public static int Multiply(Foo foo, int j) {
return foo.Multiply(j);
}
}
public static class Functions {
public static Func<TR> Apply<T1,T2,TR>( this T1 obj,
Func<T1,T2,TR> f, T2 val ) {
return () => f(obj, val);
}
}
public class Main {
public static void Run() {
var x = new Foo {Value = 10};
// the line below won't compile ...
var result = x.Apply(FooExt.Multiply, 5);
// but this will:
Func<Foo, int, int> f = FooExt.Multiply;
var result = x.Apply(f, 5);
}
}
I believe this is the result of the VS2008 C# compiler's inability to correctly infer the types involved when converting a method group to a delegate. @Eric Lippert discusses this behavior in his post C# 3.0 Return Type Inference Does Not Work On Method Groups.
If I recall correctly, some improvements were made in the new C# compiler that's part of VS2010 which expands the cases where method group inference is possible.
Now, the rules for type inference are quite complicated, and I'm far from an expert in this subject. Hopefully someone with some real knowledge can address this question if I am mistaken.
精彩评论