代码之家  ›  专栏  ›  技术社区  ›  Erik83

代表CreateDelegate从MethodInfo获取Func<>不适用于double类型?

  •  4
  • Erik83  · 技术社区  · 8 年前

    我正在尝试为double创建func。比较。

    我是这样创建的:

           var method = typeof(double).GetMethod("CompareTo", new Type[] { typeof(double) });
    
           var func = (Func<double, double, int>)Delegate.CreateDelegate(typeof(Func<double, double, int>), method);
    

    它适用于字符串。比较如下:

           var method = typeof(string).GetMethod("CompareTo", new Type[] { typeof(string) });
    
           var func = (Func<string, string, int>)Delegate.CreateDelegate(typeof(Func<string, string, int>), method);
    

    我得到一个参数异常,表示“目标方法无法绑定,因为其签名或安全透明度与委托类型不兼容”(从瑞典语自由翻译)

    怎么了?

    1 回复  |  直到 8 年前
        1
  •  3
  •   Marc Gravell    8 年前

    IIRC“扩展参数并将第一个作为目标”技巧仅适用于引用类型,例如 string -大概是因为这个 例子 方法调用变为静态调用 住址 而不是简单地 加载 这两个论点。您可以通过以下方式绕过它(不是很优雅):

    var dm = new DynamicMethod(nameof(double.CompareTo), typeof(int),
         new[] { typeof(double), typeof(double) });
    var il = dm.GetILGenerator();
    il.Emit(OpCodes.Ldarga_S, 0);  // load "ref arg0"
    il.Emit(OpCodes.Ldarg_1);      // load "arg1"
    il.Emit(OpCodes.Call, method); // call CompareTo
    il.Emit(OpCodes.Ret);
    var func = (Func<double, double, int>)dm.CreateDelegate(
         typeof(Func<double, double, int>));
    

    Func<double, double, int> func = (x,y) => x.CompareTo(y);