CreateDelegate未知类型 [英] CreateDelegate with unknown types

查看:97
本文介绍了CreateDelegate未知类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建委托读/在运行时写未知类型的类的属性。

I am trying to create Delegate for reading/writing properties of unknown type of class at runtime.

我有一个泛型类主< T> 和方法,其是这样的:

I have a generic class Main<T> and a method which looks like this:

Delegate.CreateDelegate(typeof(Func<T, object>), get)

其中, GET 的MethodInfo 应阅读财产。问题是,当属性返回 INT (我想出现这种情况的值类型)上述code抛出ArgumentException的,因为该方法不能绑定。如果字符串它工作得很好。

where get is a MethodInfo of the property that should be read. The problem is that when the property returns int (I guess this happens for value types) the above code throws ArgumentException because the method cannot be bound. In case of string it works well.

要解决,我改变了code,使相应的委托类型是通过使用 MakeGenericType 所产生的问题。所以,现在的code是:

To solve the problem I changed the code so that corresponding Delegate type is generated by using MakeGenericType. So now the code is:

Type func = typeof(Func<,>);
Type generic = func.MakeGenericType(typeof(T), get.ReturnType);
var result = Delegate.CreateDelegate(generic, get)

现在的问题是,在创建委托实例通用所以我必须用 DynamicInvoke 这将是作为慢作为使用纯反射阅读领域。

The problem now is that the created delegate instance of generic so I have to use DynamicInvoke which would be as slow as using pure reflection to read the field.

所以我的问题是,为什么是,code中的第一个片段失败,值类型。据 MSDN 的它应该工作,因为它说,

So my question is why is that the first snippet of code fails with value types. According to MSDN it should work as it says that

委托的返回类型是一个方法的返回类型兼容,如果方法的返回类型比委托的返回类型

The return type of a delegate is compatible with the return type of a method if the return type of the method is more restrictive than the return type of the delegate

和如何执行委托在第二段,这样它比反射更快。

and how to execute the delegate in the second snippet so that it is faster than reflection.

感谢。

推荐答案

下面是为您解决问题的方法之一。创建一个泛型方法:

Here's one way to solve your problem. Create a generic method:

public static Func<T, object> MakeDelegate<U>(MethodInfo @get)
{
    var f = (Func<T, U>)Delegate.CreateDelegate(typeof(Func<T, U>), @get);
    return t => f(t);
}

这样一来,C#的编译器会插入必要的拳击(如果有的话)来转换照顾 F(T)(类型为 U )以对象。现在,您可以使用反射来调用这个 MakeDelegate 方法 U 设置为 @ get.ReturnType ,以及你回来将是一个什么 Func键&LT; T,对象&gt; 可以无需诉诸调用使用 DynamicInvoke

This way, C#'s compiler takes care of inserting the necessary boxing (if any) to convert f(t) (of type U) to object. Now you can use reflection to call this MakeDelegate method with U set to @get.ReturnType, and what you get back will be a Func<T, object> which can be called without needing to resort to using DynamicInvoke.

这篇关于CreateDelegate未知类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆