问题描述
我正在使用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中是否存在任何可能的方法属性或代码检查注释:
例如:
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 ...
}
}