我正试图通过为Getter
和Setter
方法创建委托来改进我的反射代码。
我的代码是这样的:
MyObject obj = new MyObject();
var prop = obj.GetType().GetProperty("Prop");
var getType = typeof(Func<>).MakeGenericType(prop.PropertyType);
var setType = typeof(Action<>).MakeGenericType(prop.PropertyType);
var getMethod = prop.GetGetMethod().CreateDelegate(getType, obj);
var setMethod = prop.GetSetMethod().CreateDelegate(setType, obj);
// I'd like to change this section and not to use a dynamic!!
dynamic castedGet = Convert.ChangeType(getMethod, getType);
dynamic castedSet = Convert.ChangeType(setMethod, setType);
CreateDelegate
返回Delegate
,使用DynamicInvoke
不是性能明智。
我将Delegate
强制转换(硬编码)为Action<T> Func<T>
,并看到我的性能有了巨大的提高。
然后我试图在运行时将Delegate
转换为Action<T> Func<T>
(使用Convert.ChangeType
和dynamic
),我的性能受到伤害-可能是由于我使用dynamic
类型。
我很确定没有
dynamic
我也能做到。我猜测解决方案与expression trees
有关,但我不确定如何编写这样的代码。如果有人有一个不使用expression trees
的好解决方案,那么听到它也会很有趣。
如果您的目标是能够在不知道编译时返回类型的情况下调用操作/函数,那么您可能希望最终使用Action<object>
和Func<object>
,对吗?
你可以做到这一点,而不必编译表达式树或任何东西,像这样:
// Use reflection to create the action, invoking the method below.
var setAction = (Action<object>) this.GetType()
.GetMethod("CastAction", BindingFlags.Static | BindingFlags.NonPublic)
.MakeGenericMethod(prop.PropertyType)
.Invoke(null, new object[]{setMethod});
// invoke the action like this:
object value = 42; // or any value of the right type.
setAction(value);
使用辅助方法:
private static Action<object> CastAction<T>(Delegate d)
{
var action = (Action<T>)d;
return obj => action((T)obj);
}
我的测试表明,这比使用dynamic
大约快25%,比仅使用obj.Prop = 2
;
是否需要使用Action
如果没有,可以使用PropertyInfo.GetMethod()和SetMethod()
MyObject obj = new MyObject();
PropertyInfo prop = obj.GetType().GetProperty("Prop");
MethodInfo getter = prop.GetMethod();
getter.Invoke(...)
MethodInfo setter = prop.SetMethod();
setter.Invoke(...)