【问题标题】:Delegate.CreateDelegate to get Func<> from MethodInfo does not work for double type?Delegate.CreateDelegate 从 MethodInfo 获取 Func<> 不适用于双精度类型?
【发布时间】:2018-01-17 13:12:16
【问题描述】:

我正在尝试使用为 double.CompareTo 创建一个函数。

我是这样创建的:

       var method = typeof(double).GetMethod("CompareTo", new Type[] { typeof(double) });

       var func = (Func<double, double, int>)Delegate.CreateDelegate(typeof(Func<double, double, int>), method);

这样的 string.CompareTo 可以正常工作:

       var method = typeof(string).GetMethod("CompareTo", new Type[] { typeof(string) });

       var func = (Func<string, string, int>)Delegate.CreateDelegate(typeof(Func<string, string, int>), method);

我得到一个参数异常说“目标方法不能被绑定,因为它的签名或安全透明度与委托类型不兼容”(从瑞典语免费翻译)

怎么了?

【问题讨论】:

    标签: c# delegates func


    【解决方案1】:

    IIRC“扩展参数并将第一个作为目标”技巧仅适用于引用类型,例如string - 大概是因为这个 instance 方法调用变成了带有 address 第一个参数,而不是简单地加载两个参数。你可以绕过它——不是很优雅——通过:

    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);
    

    【讨论】:

    • 那很不幸。使用您建议的方式的性能如何?我正在考虑让我的变量动态化只是为了绕过它......但这还有其他一些问题......
    • @Erik83 只要您不一遍又一遍地创建它,所以我们只讨论 执行 时间:非常快 - 请注意,您可能应该 已经缓存你从CreateDelegate得到的任何东西——它不是免费的
    猜你喜欢
    • 2019-03-09
    • 2014-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-28
    相关资源
    最近更新 更多