使用反射创建访问器代理,处理未知属性类型。

5

在.NET 2.0(使用C# 3.0),当我不知道编译时的类型时,如何通过反射创建属性访问器的委托?

例如,如果我有一个类型为int的属性,我可以这样做:

Func<int> getter = (Func<int>)Delegate.CreateDelegate(
    typeof(Func<int>),
    this, property.GetGetMethod(true));
Action<int> setter = (Action<int>)Delegate.CreateDelegate(
    typeof(Action<int>),
    this, property.GetSetMethod(true));

但是如果我在编译时不知道属性的类型,我就不知道该怎么做。


1
不确定,但以下问题似乎相关:https://dev59.com/MUfRa4cB1Zd3GeqP70tX - Till
Func<T>是.NET 3.5中的一个类型....这是一个自定义的Func<T>吗? - Marc Gravell
@Marc Gravell - 哎呀,我实际上是在一个针对错误平台的草稿项目中玩耍,但它确实可以在.NET 2.0中使用自定义Func<T>。 - Ergwun
1个回答

3
你所需要的是:

以下是必备条件:

Delegate getter = Delegate.CreateDelegate(
    typeof(Func<>).MakeGenericType(property.PropertyType), this,
    property.GetGetMethod(true));
Delegate setter = Delegate.CreateDelegate(
    typeof(Action<>).MakeGenericType(property.PropertyType), this,
    property.GetSetMethod(true));

然而,如果您希望提高性能,使用DynamicInvoke()仍然不够快。您可能需要考虑元编程来编写一个接受/返回object的包装器。或者可以尝试使用HyperDescriptor,它可以为您完成这项工作。


https://dev59.com/sXE95IYBdhLWcg3wCJRf 这个问题怎么样? - Till
@Till 如果你指的是被接受的答案...如果你事先不知道类型,那么你将不得不使用MakeGenericMethod();然后它使用反射来创建一个委托,以便立即使用一次并丢弃。坦白地说,在那个例子中,原始反射(GetValue()/SetValue())会更好。 - Marc Gravell
@Marc Gravel - 是的,我试图为了性能而这样做。当我有更多时间时,我会查看HyperDescriptor - 看起来很棒。 - Ergwun
@Ergwun 如果你需要更轻量级的东西,我可以向你介绍另外三种实现类似目标的方法;让我知道。 ILGenerator 跃入脑海。 - Marc Gravell
@Ergwun稍后会添加一些内容。 - Marc Gravell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接