C#属性或代码检查注释,以鼓励或阻止从虚拟方法覆盖中调用基本方法

问题描述

我正在使用Rider在Unity中进行C#项目。

有时我会看到一个带有空虚方法的基类,然后是一个覆盖该方法的派生类。即使基本方法为空,方法重写也有对base.MethodName()的显式调用

public class A
{
    public virtual void Method1() { }

    public virtual void Method2()
    {
        // Important logic performed here!
    }
}

public class B : A
{
    public override void Method1()
    {
        base.Method();

        // Do something else ...
    }

    public override void Method2()
    {
        // Do something here ...
    }
}

在Rider的IL Viewer中查看方法时,即使该方法为空,也包括对基本方法调用

C#或Rider中是否存在任何可能的方法属性代码检查注释:

  1. 调用空的基本方法生成编译器或代码检查警告。

  2. not 调用 not 为空的基本方法时,生成编译器或代码检查警告。

例如:

public class A
{
    [OmitCallFromOverride]
    public virtual void Method1() { }

    [RequireCallFromOverride]
    public virtual void Method2()
    {
        // Important logic performed here!
    }
}

我可以想象一个场景,其中多个派生类覆盖了一个方法,并且一个或多个错误地未能调用方法,这可能导致意外行为。或在不必要的情况下调用空的基本方法的情况,这可能很浪费,但不可能破坏任何东西。

虽然我主要是在询问是否存在此类属性代码检查注释,但我也很好奇要知道人们将如何处理这些情况,例如仅始终从覆盖中调用基本方法,将重要逻辑排除在外基本虚拟方法,或使用其他一些方法来传达是否需要或不需要基本方法调用

解决方法

在调用基础时生成编译器或代码检查警告 空的方法。

据我所知,在C#中,没有警告为空方法。因此,我认为调用为空的基本方法时没有警告
但是您可以自由地为您写一个:Write your first analyzer and code fix

不调用基时生成编译器或代码检查警告 不是空的方法。

不是在C#中,我认为强制派生类调用基本方法不是一个好主意。我可以理解,在您的情况下,如果所有派生类方法都始终调用基本方法,那将是很好的选择,但是这种情况很少见。通常,当我们需要棘手(不直观)的规则时,这意味着我们的解决方案不是很清晰,否则容易出错。

将重要的逻辑保持在基本虚拟方法之外

如果需要调用A.Method1,也许不建议将其作为virtual方法。当您想给派生类一个使用它的机会,或者用一个更合适的版本覆盖它时,您可以使用一种virtual方法。
我为您提出了一个可能适合您的方案的解决方案。

abstract class A
{        
    public abstract void Method1();

    public virtual void Method2() { }

    public void MustBeCalled() 
    { 
        // Here you can put the logic you had in Method1,you need to execute this code,so this method can't be overwrited.             
    }

    public void TemplateMethod()
    {
        Method1();
        MustBeCalled();
        // Do something else ...
    }

}