如何在运行时或编译时替换自动实现的c#get body?

时间:2010-06-17 06:29:34

标签: .net linq lambda custom-attributes dynamic-programming

我一直试图弄清楚这一点,但我想我对.Net Framework的了解并不是那么深,问题并不完全是谷歌,但如果我能得到一个点头正确的方向我确信我可以用这种或那种方式实现它。

我希望能够声明一个用自定义属性修饰的属性:

public MyClass {

    [ReplaceWithExpressionFrom(typeof(SomeOtherClass))]
    public virtual bool MyProperty { get; }

}

public SomeOtherClass : IExpressionHolder<MyClass, bool> {

    ...
}

public interface IExpressionHolder<TArg, TResult> {
    Expression<Func<TArg, TResult>> Expression { get; }
}

然后以某种方式 - 这是我无法计算的部分 - 用一段自定义代码替换自动生成的getter实现,如:

Type expressionHolderType = LookupAttributeCtorArgTypeInDeclarationOfPropertyWereReplacing();
return ReplaceWithExpressionFromAttribute.GetCompiledExpressionFrom(expressionHolderType)(this);

我不确定如何做的主要事情是替换get的自动实现。

首先想到的是PostSharp,但这比我关心的依赖更复杂。我更喜欢一种编码方式,而不使用附加到构建的后处理(我认为这是PostSharp如何在其中解决其钩子的问题)。

我不太确定的另一部分是如何检索传递给ReplaceWithExpressionFrom属性的特定实例化的类型参数(它装饰了我想要替换它的主体的属性;换句话说,怎么做我得到typeof(SomeOtherClass),我正在编写get body替换码。我计划从IExpressionHolder的具体实例中缓存已编译的表达式,因为我不希望每次检索到该属性时都这样做。

我认为这只是得到是可能的。至少我认为我应该能够搜索一个程序集以查找用该属性修饰的任何方法,并以某种方式代理该类或只是替换IL或..某些东西?而且我希望尽可能顺利地进行集成,所以如果可以在没有明确调用注册或初始化方法的情况下完成,那就太棒了。

谢谢!

2 个答案:

答案 0 :(得分:2)

也许我会为此得到一个downvote,但为什么你想要一个属性呢?

您想要的是虚拟通话。为什么不简单地将MyClass子类化并实现虚拟调用?

或者您可以使用代理字典来进行相应的函数调用。

答案 1 :(得分:1)

似乎无法在运行时替换方法的实现。

它可以在编译时替换,因为PostSharp使用IL重写&amp;编织。

此外,生成的代理可以覆盖虚拟成员 - 尽管这需要通过集中点汇集对象来创建代理,而代理可以代替真实的东西(a NHibernate)。