2017-06-05 75 views
1

从C#5.0规范为什么不能在派生类中声明操作符来隐藏在基类中声明的操作符?

3.6签名和重载

...

操作者的签名由运营商的名称和每一个的类型的其形式参数,在 从左到右的顺序考虑。运营商的签名特别是 不包括结果类型。在基类中声明

...

10.10运营商

...

同其他成员一样,运营商正在通过派生类继承 。由于运算符声明总是要求 表示操作员被宣布为运营商的签名参加 类或结构,它是不可能在派生类中声明的 操作隐藏在 声明的操作基类。因此,新的修饰符从不需要,因此在运算符声明中不允许使用 。

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

谢谢。

+0

不清楚......既然你无法匹配派生类中的基类操作符的签名你期望隐藏的发生如何? –

+1

@Alexei:什么阻止你在这两个类中编写'static public bool operator <(Base b,Derived d)'? –

+1

@BenVoigt好点...刚试过 - 不会抱怨隐藏,但在通话时变得模糊不清。 (不知道为什么一个人会明智地做到这一点) –

回答

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. 对于操作员来说,隐藏并没有什么意义,因为在父类和子类中使用完全相同的签名很难做出有意义的操作符。在注释中你可以看到,仍然有可能创建这样的操作符(这是无用的),但即使这样,它也不会隐藏,因为如果它隐藏起来 - 应该选择其中一个操作符(从子类或父类中选择) ),但是编译器抱怨含糊不清。对于常规方法隐藏通常是有用的,因此是允许的。

相关问题