【问题标题】:What's wrong with bodyless abstract methods in abstract class?抽象类中的无体抽象方法有什么问题?
【发布时间】:2015-10-26 04:26:36
【问题描述】:

我正在重构一个预先存在的解决方案。我使用 ReSharper,我注意到代码检查规则被触发。有一个抽象类具有无主体方法签名,旨在强制派生类(其中有几个)。据我所知,这是(或至少是一种)正确的做事方式。然而,ReSharper 抱怨“类型成员永远不会通过基类型访问”并且“仅使用 [方法] 的覆盖”。以下是复制相关问题的示例代码:

public abstract class MyAbstractClass
{
    public abstract void CreateSomething();
    public abstract void ReadSomething();
    public abstract void InsertSomething();
}

public class MyDerivedClass : MyAbstractClass
{

    public override void CreateSomething()
    {
        throw new NotImplementedException();
    }

    public override void ReadSomething()
    {
        throw new NotImplementedException();
    }

    public override void InsertSomething()
    {
        throw new NotImplementedException();
    }
}

顺便说一句,还有其他成员排除了将抽象类作为接口的可能性。 ReSharper 建议对抽象类中的 3 个方法进行更改。它的建议是使它们成为受保护的、虚拟的、非抽象的,或者简单地将它们从抽象类中删除并只将它们放在派生类中。最初编写此代码的人是为了让每个派生类都实现这些方法,并让这些方法在派生类中公开。那么,有什么方法可以改变它以使其更有效吗?如果不是,为什么 ReSharper 对此有异议?

【问题讨论】:

  • 您是否打开了“解决方案范围分析”?右下角,绿色雷达之类的东西。
  • @JeroenVannevel - 是的,我愿意。
  • 它告诉你,因为它注意到解决方案中没有从基类实现的其他子类,基本上使它无用。令人惊讶的是,它在public 类中显示了这个警告——你确定是这样吗?验证我的建议:在您的解决方案中添加第二个类并让它从抽象类继承。这会消除警告吗?
  • @bubbleking 这是因为您的代码都没有在MyAbstractClass 上运行。从这个意义上说,是的,抽象类是没有意义的。编写一个存根方法,它接受一个MyAbstractClass 对象并调用该对象上的方法。这应该使警告消失。但在任何情况下,您都可以放心地忽略它(除非您在开发结束时收到警告,那么如果您从未真正在 MyAbstractClass 对象上使用过调用 CreateSomething,则可能需要重新访问架构。跨度>
  • 补充@Rob 所指出的,在您使用派生类的地方,您可以将其声明为基类。有些人会争辩说,在声明变量时,你应该总是使用尽可能少的特定类型,如果你这样做了,这个问题就会消失。

标签: c# resharper abstract-class


【解决方案1】:

因为您从不使用 MyAbstractClass 类型的引用访问该方法,所以将其设为抽象成员是没有意义的——您可以将其完全排除在基类之外,一切都会编译得很好。

【讨论】:

  • 我从前一个开发人员的意图中读到的重点是确保所有派生类都实现这些方法。如果排除在基类之外,这怎么可能?
  • @bubbleking 这可能是来自 resharper 的警告 现在的代码 - 您不需要使用抽象类。尝试将您的对象转换为 MyAbstractClass 并使用该方法。所以代替这个:var something = new MyDerivedClass(); something.CreateSomething(); 使用:MyAbstractClass something = new MyDerivedClass(); something.CreateSomething();。在任何情况下,您都可以忽略来自 resharper 的警告,因为将来您可能通过MyAbstractClass 引用这些方法(否则说不需要抽象方法是正确的)。
  • @Rob - 这是一个绝妙的解释。也许将您的 cmets 组合成一个答案?
  • 我已经接受了这个答案,尽管觉得它有些草率,因为@Rob 的评论更清楚了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-26
  • 2017-09-26
  • 2012-11-29
  • 2011-07-10
  • 1970-01-01
  • 2014-10-30
相关资源
最近更新 更多