【问题标题】:CreateDelegate() System.ArgumentException method signature mismatchCreateDelegate() System.ArgumentException 方法签名不匹配
【发布时间】:2021-06-12 14:05:48
【问题描述】:

我一直在尝试使用反射来比较在编译时类型未知的对象,而不是每次尝试使用 CreateDelegate() 时都调用 Invoke()。到目前为止,我已经让它在一个用于基元等的通用类型类中工作,但是我遇到了 KeyValuePair 类型的对象的砖墙。它抛出

System.ArgumentException: '无法绑定到目标方法,因为 其签名或安全透明度与 委托类型。'

当调用 CreateDelegate() 时,即使方法签名与提供给 Invoke() 和从 Invoke() 返回的类型相匹配,我也不知道我做错了什么。重现异常的最少代码如下:

static void Main(string[] args)
{
    var kvp = new KeyValuePair<string, string>("test key", "test value");

    var getKeyMethod = typeof(KeyValuePair<string, string>).GetProperty("Key").GetGetMethod();
    Console.WriteLine(getKeyMethod.Invoke(kvp, null));  //works fine

    var getKey = (Func<KeyValuePair<string, string>, string>) getKeyMethod.CreateDelegate(typeof(Func<KeyValuePair<string, string>, string>));  //exception thrown here
    Console.WriteLine(getKey(kvp));  //never gets here
}

我意识到使用表达式树也可以实现同样的事情,并且我已经使用相同的方法签名来实现这一点,如下所示:

    ParameterExpression targetExp = Expression.Parameter(typeof(KeyValuePair<string, string>), "target");
    MemberExpression propertyExp = Expression.Property(targetExp, typeof(KeyValuePair<string, string>).GetProperty("Key"));
    var getKeyMethod = Expression.Lambda<Func<KeyValuePair<string, string>, string>>(propertyExp, targetExp).Compile();

尽管如此,我想了解这里出了什么问题(表达式树也有点慢,但我主要是因为无法正常工作而感到恼火)。

【问题讨论】:

    标签: c# .net reflection delegates


    【解决方案1】:

    KeyValuePair&lt;,&gt; 是一个结构。结构和委托有特殊的规则。要访问实例方法,您基本上需要一个带有ref 参数的委托。例如,以下内容按预期工作:

    // define delegate
    delegate string RefDel(ref KeyValuePair<string, string> kvp);
    
    // in method 
    var kvp = new KeyValuePair<string, string>("test key", "test value");
    
    var getKeyMethod = typeof(KeyValuePair<string, string>).GetProperty("Key").GetGetMethod();
    var getKey = (RefDel)getKeyMethod.CreateDelegate(typeof(RefDel));
    
    Console.WriteLine(getKey(ref kvp));  // "test key"
    

    See here 是一个活生生的例子。

    【讨论】:

    • 或者换句话说,结构体的this被定义为ref参数,见ECMA-335 I.8.9.7
    猜你喜欢
    • 2021-05-15
    • 1970-01-01
    • 2018-01-15
    • 1970-01-01
    • 1970-01-01
    • 2018-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多