非构造函数虚拟方法的类似构造函数基本调用的执行?

huangapple go评论74阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2023年2月14日 00:29:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/75438661.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定