C# 无法从Func转换<;T、 T,T>;to Func<;T、 T,T>;

C# 无法从Func转换<;T、 T,T>;to Func<;T、 T,T>;,c#,generics,casting,delegates,C#,Generics,Casting,Delegates,我被这个错误弄糊涂了: 无法将类型“System.Func[c:\Program Files(x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll]”隐式转换为“System.Func[c:\Program Files(x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll]”path\to\my

我被这个错误弄糊涂了:

无法将类型“System.Func[c:\Program Files(x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll]”隐式转换为“System.Func[c:\Program Files(x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll]”path\to\my\project\Operators.cs

这些类型都是一样的,为什么它还要试着做一个演员呢?代码如下:

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);
    }
}
公共静态类运算符
{
私有静态函数_add=null;
公共静态T添加(T a,T b)
{
如果(_add==null){
var param1Expr=Expression.Parameter(typeof(T));
var param2Expr=Expression.Parameter(typeof(T));
var addExpr=Expression.Add(param1Expr,param2Expr);
var expr=Expression.Lambda(addExpr、param1Expr、param2Expr);
_add=expr.Compile();//问题在于您的方法是泛型的,引入了一个新的类型参数
T
。因此方法外部的
T
与方法内部的
T
不同

只需将您的方法更改为非泛型:

public static T Add(T a, T b)
…应该没问题

更清楚地说,您的代码目前相当于:


您的
操作符的
T
类和
Add
T
类型参数是不同的类型,因此不能保证这些类型是兼容的

例如,您可以执行以下操作:

Operators<string>.Add<int>(1, 2);
运算符。添加(1,2);
编译器对此发出警告:

类型参数“T”与外部的类型参数具有相同的名称 输入“运算符”


在警告栏上有很好的位置。首先检查警告总是值得的:)哈。我关闭了警告,因为它是对我声明但尚未使用的变量的垃圾邮件:-)这很好。你应该从编译器那里得到一个警告。不是吗?@EricLippert:有一个警告,但我暂时关闭了它们当我重构一堆东西时,我收到了太多关于未使用变量的警告。
Test.cs(19,20): error CS0029: Cannot implicitly convert type
        'System.Func<TM,TM,TM>' to 'System.Func<TC,TC,TC>'
Operators<string>.Add<int>(1, 2);