Delegate.CreateDelegate获取Func<>来自MethodInfo不适用于double类型?

时间:2018-01-17 13:12:16

标签: c# delegates func

我试图使用为double.CompareTo创建一个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);

它适用于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);

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

有什么问题?

1 个答案:

答案 0 :(得分:3)

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