Ami*_*ich 9 c# reflection casting
我正在尝试通过为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);
Run Code Online (Sandbox Code Playgroud)
CreateDelegate返回a Delegate并且使用DynamicInvoke 不是性能明智的.
我Delegate投入(硬编码)进入Action<T> \ Func<T>并看到我的表现大幅增加.
然后我试着投了Delegate到Action<T> \ Func<T>在运行时(使用Convert.ChangeType和dynamic)和我的表现受到伤害-这可能是由于这样的事实,我使用一个dynamic类型.
我很确定我可以不用这样做dynamic.
我想解决方案与此有关expression trees,但我不确定如何编写这样的代码.如果某人有一个不使用的好解决方案,那么expression trees听到它也会很有趣.
如果您的目标是能够在编译时不知道返回类型的情况下调用操作/函数,那么您可能希望以 and 结束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);
Run Code Online (Sandbox Code Playgroud)
使用这个辅助方法:
private static Action<object> CastAction<T>(Delegate d)
{
var action = (Action<T>)d;
return obj => action((T)obj);
}
Run Code Online (Sandbox Code Playgroud)
我的测试表明这比使用 大约快 25% dynamic,比直接说 慢大约 45% obj.Prop = 2;