【问题标题】:Why can't an operator declared in a derived class hide an operator declared in a base class?为什么派生类中声明的运算符不能隐藏基类中声明的运算符?
【发布时间】:2017-06-05 05:10:34
【问题描述】:

来自 C# 5.0 规范

3.6 签名和重载

...

运算符的签名由运算符的名称和每个形式参数的类型组成,在 从左到右排序。操作员的签名专门做 不包括结果类型。

...

10.10 运算符

...

像其他成员一样,在基类中声明的运算符是继承的 通过派生类。因为操作符声明总是需要 声明运算符参与的类或结构 在操作员的签名中,它是不可能的 在派生类中声明的运算符以隐藏在派生类中声明的运算符 基类。因此,永远不需要新的修饰符,因此 绝对不允许,在操作符声明中。

  1. 第一段没有说“其中的类或结构 运营商被声明”是运营商签名的一部分。所以 什么是“操作员声明总是需要类或 声明操作员参与的结构 第二段中的操作员签名是什么意思?
  2. 是否适用于操作员的签名,但不适用于方法的签名? 签名?
  3. 如果“在派生类中声明的运算符是不可能的 隐藏在基类中声明的运算符”,是否有可能 方法以及为什么?

谢谢。

【问题讨论】:

  • 不清楚...由于您无法匹配派生类中基类运算符的签名,您希望如何隐藏?
  • @Alexei:是什么阻止你在两个班级都写static public bool operator<(Base b, Derived d)
  • @BenVoigt 好点...刚试过 - 不抱怨隐藏,但在通话时变得模棱两可。 (不知道为什么有人会出于明智的意图这样做)
  • @BenVoigt、Tim 和 Alexei:出于好奇,为什么这个问题很重要,为什么要逐字阅读规范?我的意思是我们不能说规范可能是错误的吗?我问这个问题是因为为什么要如此仔细地阅读规范?
  • @CodingYoshi C# 通常旨在防止可能令人困惑的事情(例如不允许在嵌套范围内使用相同的变量) - 因此了解如何/为什么编写特定规则是个好主意。 IE。如果尝试创建自定义数字类型,对运算符重载规则缺乏很好的理解,可能会导致相当多的痛苦......(顺便说一句,如果与运算符重载相关的 C# 规范的一部分是错误的,我会感到非常惊讶。到现在经历了7个版本,确实也可能是错的)

标签: c#


【解决方案1】:
  1. 运算符基本上是(但不总是)具有特殊语法的静态函数。 + 类似于static T Add(T first, T second)= 类似于static void Assign(ref T location, T value) 等等。 C# 中的某些运算符可以重载,有些(例如赋值= 运算符)不能。当编译器看到一个可以重载的运算符时 - 它应该找到相应的静态函数来使用(除非这样的函数是内置的,例如整数加法)。所以假设编译器看到a + b,其中aTypeAbTypeB。编译器转到 TypeATypeB 类型(如果需要,还有它们的父级),以查看是否存在与给定案例匹配名称和签名的静态函数。在这种情况下,它应该是public static int op_Addition(TypeAOrBaseType a, TypeBOrBaseType b)operator + 将被编译为名称为op_Addition 的方法)。从那里应该清楚为什么你声明运算符的类应该参与运算符签名 - 如果你在类型 TypeA 中声明类似 static int operator +(TypeC a, TypeD b) 的东西 - 它永远不能使用,因为当你添加 TypeCTypeD - 编译器永远不会在TypeA 中寻找相应的运算符 - 为什么会这样?它将查看TypeCTypeD

  2. 当然,常规方法不是这样——在常规方法中,您可以在签名中使用任何类型,并且不需要在签名中使用声明类型的实例(尽管您可能会说在实例方法中声明类型始终是隐式传递的,可以与 this 关键字一起使用。

  3. 隐藏对运算符没有多大意义,因为很难在父类和子类中生成具有完全相同签名的有意义的运算符。在 cmets 中,您可以看到仍然可以制作这样的运算符(这是无用的),但即使那样它也没有隐藏,因为如果它被隐藏 - 应该在使用时选择其中一个运算符(来自子类或来自父类),而是编译器抱怨歧义。对于常规方法,隐藏通常很有用,因此是允许的。

【讨论】:

    猜你喜欢
    • 2021-07-03
    • 2010-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-02
    • 1970-01-01
    • 2012-06-06
    相关资源
    最近更新 更多