【问题标题】:Declare most complex method in base class as virtual将基类中最复杂的方法声明为虚拟方法
【发布时间】:2014-10-09 15:02:18
【问题描述】:

我一直在阅读 Jeffrey Richter 的 CLR by C# 一书,他认为在基类中定义方法时,如果有一个方法要声明为虚拟方法并且它有一些便利重载,最复杂方法应该是虚拟方法,其他方法应该保留为非虚拟方法。这是他给出的例子:

public class Set {
    private Int32 m_length = 0;
    // This convenience overload is not virtual
    public Int32 Find(Object value) {
        return Find(value, 0, m_length);
    }
    // This convenience overload is not virtual
    public Int32 Find(Object value, Int32 startIndex) {
        return Find(value, startIndex, m_length - startIndex);
    }
    // The most feature-rich method is virtual and can be overridden
    public virtual Int32 Find(Object value, Int32 startIndex, Int32 endIndex) {
        // Actual implementation that can be overridden goes here...
    }
    // Other methods go here
}

这里的理性是什么?

【问题讨论】:

  • 在我看来,他只是在举一个polymorphism 的例子,他的重载。至于为什么要使用virtual this 是一个很好的答案。
  • 不,实际上这本书是关于 CLR 的。多态性在本书中被视为一个已知的概念。这实际上是一个示例,说明为什么在有许多不同的便利重载时,您应该始终只将更复杂的一个设置为虚拟,而将其余部分保留为非虚拟。
  • 他说这样做会使其更具多态性?那是因为只有一种方法可以覆盖而不是很多吗?如果是这样,为什么它更具有多态性?
  • 我以前从未听说过这个,但它是有道理的。我很想看到有人提出一个继承类的例子,它运行良好。
  • 嗯,将所有重载设为虚拟在技术上没有任何问题,但我认为这个想法是,只有主要方法,即采用所有参数的方法,是唯一需要的方法 被覆盖。其他的只是代理到这个主要方法,转发他们的参数并为其余的传递 null 或一些默认值。无论在任何继承结构中覆盖主方法多少次,这些都将继续正常工作。

标签: c# inheritance clr virtual-functions


【解决方案1】:

答案是 - DRY principle - a single source of truth。有最复杂的方法A。 B、C 和 D 都使用其功能的子集。所以程序员以这种方式创建,并且所有进一步的代码修改都基于您保持 A、B、C、D 之间的关系的假设。如果您允许所有 B、C、D 都是可覆盖的,那么您就打破了提出的想法在课堂上。

代码可读性受到影响,人们阅读了您的基类,构想了它的工作原理,然后阅读了您的类,并认为他们刚刚学到的东西与您的实现不一样。使团队努力工作。同样,当您在 5 年后阅读您的代码时(如果需要)。

【讨论】:

    【解决方案2】:

    原因是所有更简单的方法都是通过调用虚方法来实现的。如果这些都是虚拟的,你可能会破坏这份合同。通过只允许您更改此类的实现专业化,这些方法将遵循相同的约定。

    【讨论】:

      【解决方案3】:

      我同意杰弗里的观点;使 virtual 成为最复杂的成员是有意义的,因为对“较小”复杂成员的调用将调用最复杂的成员,因为它们是通过方法链接调用的。此外,最复杂的成员可能是包含执行函数所需的所有参数而没有任何外部依赖关系的成员。

      如果可以的话,我稍后会详细介绍。

      【讨论】:

        【解决方案4】:

        只有一个实现,其他的重载只是转发一个调用。使virtual 有意义,因为在覆盖实现时转发仍然有效。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-07-18
          • 2011-09-30
          • 2016-05-04
          • 1970-01-01
          • 2020-10-22
          • 1970-01-01
          • 1970-01-01
          • 2011-04-30
          相关资源
          最近更新 更多