【发布时间】: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