问题
I'm quite confused by this error:
Cannot implicitly convert type 'System.Func<T,T,T> [c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll]' to 'System.Func<T,T,T> [c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll]' path\to\my\project\Operators.cs
The types are identical, why is it even trying to do a cast? Here's the code:
public static class Operators<T>
{
private static Func<T,T,T> _add = null;
public static T Add<T>(T a, T b)
{
if (_add == null) {
var param1Expr = Expression.Parameter(typeof (T));
var param2Expr = Expression.Parameter(typeof (T));
var addExpr = Expression.Add(param1Expr, param2Expr);
var expr = Expression.Lambda<Func<T, T, T>>(addExpr, param1Expr, param2Expr);
_add = expr.Compile(); // <--- error occurs here
}
return _add.Invoke(a, b);
}
}
回答1:
The problem is that your method is generic, introducing a new type parameter T
. So the T
outside the method isn't the same as the T
inside the method.
Just change your method to not be generic:
public static T Add(T a, T b)
... and it should be fine.
To be clearer, your code is currently equivalent to this:
public static class Operators<TC>
{
private static Func<TC, TC, TC> _add = null;
public static TM Add<TM>(TM a, TM b)
{
if (_add == null) {
var param1Expr = Expression.Parameter(typeof(TM));
var param2Expr = Expression.Parameter(typeof(TM));
var addExpr = Expression.Add(param1Expr, param2Expr);
var expr = Expression.Lambda<Func<TM, TM, TM>>
(addExpr, param1Expr, param2Expr);
_add = expr.Compile();
}
return _add.Invoke(a, b);
}
}
Note how I've renamed the T
introduced by the class to TC
, and the T
introduced by the method to TM
. The error message now looks more reasonable:
Test.cs(19,20): error CS0029: Cannot implicitly convert type
'System.Func<TM,TM,TM>' to 'System.Func<TC,TC,TC>'
回答2:
The T
for your Operators<T>
class and the T
type parameter for Add
are different types, so there's no guarantee that the types are compatible.
For example you could do:
Operators<string>.Add<int>(1, 2);
The compiler emits a warning to this effect:
Type parameter 'T' has the same name as the type parameter from outer type 'Operators'
来源:https://stackoverflow.com/questions/15055900/cannot-convert-from-funct-t-t-to-funct-t-t