我有一个抽象基类,将在数百个派生类中使用,包括一个附加的抽象类。
至少有2个属性(我们将它们称为目的和描述,都称为字符串)将被添加到许多(但不是全部)具体的派生类中,因此我创建了接口(IPurposeful和IDescribable)以在添加它们时需要。到目前为止一切都很好。
我想要一个可以调用从我的基类派生的所有类的方法,如果该类确实是IDescribable的,那么它将验证并更新Description属性,或者如果它不是IDescribable的,则仅返回true。我想要另一种类似的方法来验证/更新Purpose属性。
我通过基类中的方法实现了这一点:
protected bool CheckDescription(bool modify = false)
{
if (this is IDescribable ele)
{
var newDesc = GetCorrectDescription();
UpdateDescription(newDesc, ele.Description, modify);
return newDesc.Equals(ele.Description);
}
else
{
return true;
}
}
SonarQube将“这是可描述的”标记为阻止程序(不好的做法),我想知道为什么吗?我能想到的另一种复制此功能的方法是将基本方法更改为此:
protected virtual bool CheckDescription(bool modify = false)
{
return true;
}
,然后将此完全相同的方法添加到可能的数百个派生类中:
protected override bool CheckDescription(bool modify = false)
{
var newDesc = GetCorrectDescription();
UpdateDescription(newDesc, Description, modify);
return newDesc.Equals(Description);
}
现在看来这是一种不好的做法。
编辑:更改了is / as模式以消除冗余
答案 0 :(得分:2)
如果您的类可能为IDescribable
,而可能为IPurposeful
,则为其提供明智的默认实现那些可能是无操作的接口,并允许您的后代类根据需要覆盖这些实现。
不需要类型检查。只需调用可覆盖的方法并遵守其结果即可。
如果您的“可选”接口不允许明智的无操作实现,请重新访问其定义。
现在,您的基类可以依靠这些接口,而不是对其进行测试。
您可能会在此处引入运行时错误-但是对于需要实现无法编译时检查的特定接口的基类方法也可以这么说。
答案 1 :(得分:0)
我决定进一步研究扩展方法,发现对于我的特殊需求,它们可以很好地工作。我想将最初的建议标记为将扩展方法视为正确的答案,但似乎找不到找到这种方法的机制。
无论如何,扩展方法满足了我的要求,即能够在一个地方为大多数派生类定义默认算法,并仅在必要时/在特定派生类中覆盖该行为。
一个缺点是我不能从“ override”方法中调用“ base”实现。这可能会导致将来需要复制代码,但值得庆幸的是,我现在还没有遇到这个问题。