如何在运行时或编译时替换自动实现的 C# get body?
我整晚都在试图解决这个问题,但我想我对 .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 或 .. 某些东西?我想让集成尽可能顺利,所以如果这可以在不显式调用注册或初始化方法的情况下完成,那就太好了。
谢谢!
I've been trying to figure this out all night, but I guess my knowledge of the .Net Framework just isn't that deep and the problem doesn't exactly Google well, but if I can get a nod in the right direction I'm sure I can implement it, one way or another.
I'd like to be able to declare a property decorated with a custom attribute as such:
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; }
}
And then somehow - this is the part I'm having trouble figuring - replace the automatically generated implementation of that getter with a piece of custom code, something like:
Type expressionHolderType = LookupAttributeCtorArgTypeInDeclarationOfPropertyWereReplacing();
return ReplaceWithExpressionFromAttribute.GetCompiledExpressionFrom(expressionHolderType)(this);
The main thing I'm not sure how to do is replace the automatic implementation of the get.
The first thing that came to mind was PostSharp, but that's a more complicated dependency than I care for. I'd much prefer a way to code it without using post-processing attached to the build (I think that's the jist of how PostSharp sinks its hooks in anyway).
The other part of this I'm not so sure about is how to retrieve the type parameter passed to the particular instantiation of the ReplaceWithExpressionFrom attribute (where it decorates the property whose body I want to replace; in other words, how do I get typeof(SomeOtherClass) where I'm coding the get body replacement). I plan to cache compiled expressions from concrete instances of IExpressionHolder, as I don't want to do that every time the property gets retrieved.
I figure this has just got to be possible. At the very least I figure I should be able to search an assembly for any method decorated with the attribute and somehow proxy the class or just replace the IL or .. something? And I'd like to make the integration as smooth as possible, so if this can be done without explicitly calling a registration or initialization method somewhere that'd be super great.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
也许我会对此投反对票,但你为什么要为此买一处房产呢?
您似乎想要的是虚拟通话。为什么不简单地子类化 MyClass 并实现虚拟调用?
或者您可以使用委托字典来进行适当的函数调用。
Maybe I'll get a downvote for this, but why do you want a property for this?
What you appear to want is a virtual call. Why not simply subclass MyClass and implement the virtual call?
Or you could use a dictionary of delegates to the appropriate function call.
似乎不可能在运行时替换方法的实现。
它可以在编译时被替换,就像 PostSharp 通过 IL 重写 & 所做的那样。编织。
此外,生成的代理可以覆盖虚拟成员 - 尽管这需要通过一个集中点来集中对象创建,在该集中点可以分发代理来代替真实的东西(类似于 NHibernate)。
It seems to not be possible to replace the implementation of a method at runtime.
It can be replaced at compile time, as PostSharp does with IL rewriting & weaving.
Also, a generated proxy can override virtual members - although this requires funneling object creation through a centralized point where proxies can be handed out in lieu of the real thing (a la NHibernate).