英文:
Enforcement of constructor-like base calls for non-constructor virtual methods?
问题
我有一个多级类层次结构,其中有一个Refresh
方法,每个级别都引入一些新字段需要刷新。换句话说,我希望"级别 3" 类刷新级别 1、2 和 3 的字段,而"级别 4" 类刷新级别 1、2、3 和 4 的字段。
基本解决方案是每个Refresh
方法都调用base.Refresh
。但我觉得这很容易被忽视。我希望有一种方法可以注释根Refresh
声明,以表明我希望在该方法的所有层次结构子类的方法体之前插入对base.Refresh
的调用,即,请在我的方法体之前插入对base.Refresh
的调用,以实现"类似构造函数的基类调用逻辑"(如果我可以选择在方法体之前或之后,即类似析构函数,那就更好了)。
据我所知,基本语言中没有这样的东西,但我想这是一个常见的问题,因此可能有一些库引入了允许执行此操作的C#注释,就像在https://stackoverflow.com/questions/35231241/enforce-super-call-on-non-constructor-methods的答案中一样,或者可能有一些合适的替代方法。是否有这样的解决方案?
英文:
I have a multi-level class hierarchy with a Refresh
method where each level introduces some new fields to be refreshed. In other words, I want the "level 3" class to refresh the fields of levels 1, 2 and 3, and the "level 4" class to refresh that of levels 1, 2, 3 and 4.
The basic solution is that each Refresh
method calls base.Refresh
. But I find this to be easy to overlook. I wish there was a way to annotate the root Refresh
declaration to say that I want "constructor-like base call logic" on that method, i.e, please insert a call to base.Refresh
before my method body for all children of that hierarchy. (If I can choose between pre and post-body i.e destructor-like, that's even better).
As far as I know there's no such thing in the base language, but I figure it's a common issue so perhaps some library introduces C# annotations that allow doing just that, as in the answer to https://stackoverflow.com/questions/35231241/enforce-super-call-on-non-constructor-methods, or some suitable alternative. Is there ?
答案1
得分: 0
你可以使用AOP和一些与Aspects相关的库来实现这种行为。
例如,你可以将PostSharp
添加到你的项目中,然后定义一个实现"Refresh"方法并将其应用于目标类的切面类,使用属性来标记。
public class RefreshCallAspect : MethodInterceptionAspect
{
public override void OnInvoke(MethodInterceptionArgs args)
{
if(args.Method.Name == "Refresh")
{
// 这里你应该查找并调用基类的方法
base.OnInvoke(args);
}
args.Proceed();
}
}
[RefreshCallAspect]
public class Level1
{
public virtual void Refresh()
{
// Level 1 刷新逻辑在这里
}
}
public class Level2 : Level1
{
public override void Refresh()
{
// Level 2 刷新逻辑在这里
}
}
public class Level3 : Level2
{
public override void Refresh()
{
// Level 3 刷新逻辑在这里
}
}
这是有关在PostSharp中拦截方法的文章。
英文:
You can implement this behavior with AOP and one of the libraries for Aspects.
For example you can add PostSharp
to your project then define an aspect class that implements the "Refresh" method and applies it to the target classes using attributes.
public class RefreshCallAspect : MethodInterceptionAspect
{
public override void OnInvoke(MethodInterceptionArgs args)
{
if(args.Method.Name == "Refresh")
{
// here you should find and call a method of a base class
base.OnInvoke(args);
}
args.Proceed();
}
}
[RefreshCallAspect]
public class Level1
{
public virtual void Refresh()
{
// Level 1 refresh logic here
}
}
public class Level2 : Level1
{
public override void Refresh()
{
// Level 2 refresh logic here
}
}
public class Level3 : Level2
{
public override void Refresh()
{
// Level 3 refresh logic here
}
}
Here is an article about Intercepting Methods in PostSharp.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论