为什么在派生类中声明的运算符不能隐藏在基类中声明的运算符?

时间:2017-06-05 05:10:34

标签: c#

来自C#5.0规范

  

3.6签名和重载

     

...

     

运算符的签名包含运算符的名称及其每个形式参数的类型,在   从左到右。运营商的签名具体   不包括结果类型。

     

...

     

10.10运营商

     

...

     

与其他成员一样,继承在基类中声明的运算符   通过派生类。因为运算符声明始终需要   声明运算符参与的类或结构   在运营商的签名中,不可能   在派生类中声明的运算符,用于隐藏在a中声明的运算符   基类。因此,永远不需要新的修饰符,因此   从不允许,在运营商声明中。

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

1 个答案:

答案 0 :(得分: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的方法。从那以后应该清楚为什么你声明运算符的类应该参与运算符签名 - 如果你在类型static int operator +(TypeC a, TypeD b)中声明类似TypeA的东西 - 它就永远不会被使用,因为当你添加{{1 }和TypeC - 编译器永远不会在TypeD中寻找相应的运算符 - 为什么会这样?它会查看TypeATypeC

  2. 当然,常规方法并非如此 - 在常规方法中,您可以在签名中使用任何类型,并且不需要在签名中使用声明类型的实例(尽管您可能会说在实例中,声明类型的实例总是被隐式传递,并且可以与TypeD关键字一起使用。

  3. 隐藏对于操作员来说没有多大意义,因为在父类和子类中使用完全相同的签名很难创建有意义的操作符。在评论中你可以看到它仍然可以制作这样的操作符(这是无用的),但即使这样它也没有隐藏,因为如果它隐藏了 - 应该选择其中一个操作符(无论是来自子类还是来自父类),而是编译器抱怨模棱两可。对于常规方法,隐藏通常很有用,因此也是允许的。