我正在尝试创建Delegate,用于在运行时读取/写入未知类型类的属性.
我有一个泛型类Main<T>和一个如下所示的方法:
Delegate.CreateDelegate(typeof(Func<T, object>), get)
Run Code Online (Sandbox Code Playgroud)
哪个get是MethodInfo应该阅读的属性.问题是当属性返回时int(我猜这种情况发生在值类型中),上面的代码抛出了ArgumentException,因为该方法无法绑定.在字符串的情况下,它运作良好.
为了解决这个问题,我更改了代码,以便使用生成相应的Delegate类型MakeGenericType.所以现在的代码是:
Type func = typeof(Func<,>);
Type generic = func.MakeGenericType(typeof(T), get.ReturnType);
var result = Delegate.CreateDelegate(generic, get)
Run Code Online (Sandbox Code Playgroud)
现在的问题是generic我必须使用创建的委托实例,DynamicInvoke这与使用纯反射来读取字段一样慢.
所以我的问题是为什么第一段代码失败了值类型.根据MSDN,它应该像它说的那样工作
如果方法的返回类型比委托的返回类型更具限制性,则委托的返回类型与方法的返回类型兼容
以及如何在第二个片段中执行委托,以便它比反射更快.
谢谢.
我需要调用在运行时通过反射确定的属性,并以高频率调用它们.所以我正在寻找具有最佳性能的解决方案,这意味着我可能会避免反思.我在考虑将属性访问器存储为列表中的Func和Action委托,然后调用它们.
private readonly Dictionary<string, Tuple<Func<object>, Action<object>>> dataProperties =
new Dictionary<string, Tuple<Func<object>, Action<object>>>();
private void BuildDataProperties()
{
foreach (var keyValuePair in this.GetType()
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(p => p.Name.StartsWith("Data"))
.Select(
p =>
new KeyValuePair<string, Tuple<Func<object>, Action<object>>>(
p.Name,
Tuple.Create(this.GetGetter(p), this.GetSetter(p)))))
{
this.dataProperties.Add(keyValuePair.Key, keyValuePair.Value);
}
}
Run Code Online (Sandbox Code Playgroud)
现在的问题是,如何将访问器分离为Func和Action为以后的调用进行分类?
仍然使用反射进行调用的天真实现如下所示:
private Func<object> GetGetter(PropertyInfo info)
{
// 'this' is the owner of the property
return () => info.GetValue(this);
}
private Action<object> GetSetter(PropertyInfo info)
{
// 'this' is the owner of the property
return v => info.SetValue(this, v); …Run Code Online (Sandbox Code Playgroud) 我们需要动态生成委托类型.我们需要根据输入参数和输出生成委托.输入和输出都是简单类型.
例如,我们需要生成
int Del(int, int, int, string)
Run Code Online (Sandbox Code Playgroud)
和
int Del2(int, int, string, int)
Run Code Online (Sandbox Code Playgroud)
任何关于如何开始这方面的指示都会非常有帮助.
我们需要解析表示为xml的表达式.
例如,我们将(a + b)表示为
<ADD>
<param type="decimal">A</parameter>
<param type="decimal">B</parameter>
</ADD>
Run Code Online (Sandbox Code Playgroud)
我们现在希望将其暴露为Func<decimal, decimal, decimal>.我们当然希望允许xml中的嵌套节点,例如:
(a + b) + (a - b * (c - d)))
Run Code Online (Sandbox Code Playgroud)
我们希望使用表达式树和Expression.Compile.
欢迎就这种方法的可行性提出建议.