c# - 在运行时将委托(delegate)转换为 Action<T> 或 Func<T>

标签 c# reflection casting

我正在尝试通过为 Getter 创建委托(delegate)来改进我的反射代码和 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.ChangeTypedynamic )我的表现受到了伤害——可能是因为我使用的是 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 慢了大约 45% ;

关于c# - 在运行时将委托(delegate)转换为 Action<T> 或 Func<T>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32698305/

相关文章:

c# - 如何通过在字符串中指定其名称来获取枚举类型

c - 为什么我需要将 -1 的值转换为字符(为 AVR 微 Controller 编译时)

c++ - 从较大的数据类型(结构)转换为较小的数据类型

c# - "Hello world"应用程序在 .NET4.0 中使用 4 个线程,但在 .NET2.0 中使用 3 个

c# - 为已经执行的任务创建延续的可靠方法是什么?

c# - 通用扩展方法 : Type argument cannot be inferred from the usage

reflection - 在运行时使用 JDK 编译器时的内存泄漏

c# - The non-generic method cannot be used with type arguments in this context 是什么意思?

c# - CanRead 和 CanWrite 对于 PropertyInfo 意味着什么?

c++ - reinterpret_cast for 'serializing' 数据,接收端的字节顺序和对齐方式