来自C#5.0规范
3.6签名和重载
...
运算符的签名包含运算符的名称及其每个形式参数的类型,在 从左到右。运营商的签名具体 不包括结果类型。
...
10.10运营商
...
与其他成员一样,继承在基类中声明的运算符 通过派生类。因为运算符声明始终需要 声明运算符参与的类或结构 在运营商的签名中,不可能 在派生类中声明的运算符,用于隐藏在a中声明的运算符 基类。因此,永远不需要新的修饰符,因此 从不允许,在运营商声明中。
感谢。
答案 0 :(得分:1)
运算符基本上(但不总是)具有特殊语法的静态函数。 +
与static T Add(T first, T second)
类似,=
与static void Assign(ref T location, T value)
类似,依此类推。 C#中的某些运算符可能会重载,某些运算符(如赋值=
运算符)不能重载。当编译器看到一个可以重载的运算符时 - 它应该找到相应的静态函数来使用(除非这样的函数是内置的,比如整数加法)。因此,假设编译器看到a + b
a
为TypeA
且b
为TypeB
。编译器转到类型TypeA
和TypeB
(以及必要时的父项)以查看是否存在具有匹配名称和签名的静态函数。在这种情况下,它应该是public static int op_Addition(TypeAOrBaseType a, TypeBOrBaseType b)
(operator +
将编译为名为op_Addition
的方法。从那以后应该清楚为什么你声明运算符的类应该参与运算符签名 - 如果你在类型static int operator +(TypeC a, TypeD b)
中声明类似TypeA
的东西 - 它就永远不会被使用,因为当你添加{{1 }和TypeC
- 编译器永远不会在TypeD
中寻找相应的运算符 - 为什么会这样?它会查看TypeA
和TypeC
。
当然,常规方法并非如此 - 在常规方法中,您可以在签名中使用任何类型,并且不需要在签名中使用声明类型的实例(尽管您可能会说在实例中,声明类型的实例总是被隐式传递,并且可以与TypeD
关键字一起使用。
隐藏对于操作员来说没有多大意义,因为在父类和子类中使用完全相同的签名很难创建有意义的操作符。在评论中你可以看到它仍然可以制作这样的操作符(这是无用的),但即使这样它也没有隐藏,因为如果它隐藏了 - 应该选择其中一个操作符(无论是来自子类还是来自父类),而是编译器抱怨模棱两可。对于常规方法,隐藏通常很有用,因此也是允许的。