首页 > 解决方案 > 我不明白为什么在基类中测试可能的接口是错误的

问题描述

我有一个抽象基类,它将用于数百个派生类,包括一个额外的抽象类。

至少有 2 个属性(我们称它们为目的和描述,都是字符串)将添加到许多(但不是全部)具体派生类中,因此我创建了接口(IPurposeful 和 IDescribable)以在需要时添加它们。到目前为止一切都很好。

我想要一个方法,我可以调用从我的基类派生的所有类,如果它确实是 IDescribable,它将验证和更新 Description 属性,或者如果它不是 IDescribable,则只返回 true。我想要另一种类似的方法来验证/更新目的属性。

我通过基类中的一个方法实现了这一点,它看起来像这样:

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 将“这是 IDescribable”检查标记为阻止程序(不好的做法),我想知道为什么?我能想到的复制此功能的唯一其他方法是将基本方法更改为:

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 模式以消除冗余

标签: c#inheritanceinterfaceabstract-base-class

解决方案


如果您的类可能IDescribable并且可能IPurposeful,那么为那些可能是无操作的接口提供合理的默认实现,并允许您的后代类根据需要覆盖这些实现。

无需类型检查。只需调用可覆盖的方法并遵守它们的结果。

如果您的“可选”接口不允许合理的无操作实现,请重新访问它们的定义。

现在您的基类可以依赖接口,而不是测试它们。


您可能会在此处引入运行时错误 - 但对于需要实现特定接口且编译时不可检查的基类方法也可以这样说。


推荐阅读