CreateDelegate() System.ArgumentException 方法签名不匹配
CreateDelegate() System.ArgumentException method signature mismatch
我一直在尝试使用反射来比较编译时类型未知的对象,而不是每次尝试使用 CreateDelegate() 时都调用 Invoke()。到目前为止,我已经在通用类型 class 中为基元等工作,但我已经 运行 进入了带有 KeyValuePair 类型对象的砖墙。它抛出
System.ArgumentException: 'Cannot bind to the target method because
its signature or security transparency is not compatible with that of
the delegate type.'
当调用 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();
尽管如此,我想了解这里到底出了什么问题(表达式树也有点慢,但我主要是因为无法正常工作而感到恼火)。
KeyValuePair<,>
是一个结构。结构和委托有特殊规则。要访问实例方法,您本质上需要一个带有 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 举个例子。
我一直在尝试使用反射来比较编译时类型未知的对象,而不是每次尝试使用 CreateDelegate() 时都调用 Invoke()。到目前为止,我已经在通用类型 class 中为基元等工作,但我已经 运行 进入了带有 KeyValuePair
System.ArgumentException: 'Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.'
当调用 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();
尽管如此,我想了解这里到底出了什么问题(表达式树也有点慢,但我主要是因为无法正常工作而感到恼火)。
KeyValuePair<,>
是一个结构。结构和委托有特殊规则。要访问实例方法,您本质上需要一个带有 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 举个例子。