2017-06-05 6 views
1

派生クラスで宣言された演算子が、基本クラスで宣言された演算子を隠すことができないのはなぜですか? C#5.0仕様から

3.6署名と

...

は、オペレータの名前とのそれぞれのタイプから成るオペレータの署名オーバーロードその左から順に の順序で考慮された仮パラメータ。オペレータの署名には、具体的には に結果の型は含まれません。

...

10.10演算子

...他のメンバーと同様

は、基本クラスで宣言され、オペレータは、派生クラスで を継承しています。 オペレータ宣言は常にオペレータがオペレータの署名に に参加すると宣言されている クラスまたは構造体を必要とするので、それは で宣言された演算子を隠すために、派生クラス内で宣言 オペレータ可能ありません基本クラス。したがって、新しい修飾子は決して必要ではないため、オペレータ宣言では は決して許可されません。

  1. 最初の段落は、オペレータの署名の一部である「演算子を れているクラスまたは構造体が宣言されている」と言うことはありません。したがって オペレータの宣言では常に、オペレータの 構造体にオペレータの 署名に参加すると宣言されている構造体が必要なのは何ですか?
  2. これはオペレータの署名に適用されますが、メソッドの 署名には適用されませんか?
  3. "派生クラス で宣言された演算子で、基本クラスで宣言された演算子を非表示にすることはできません"場合は、 メソッドが使用できますか?

ありがとうございます。

+0

派生クラスの基底クラス演算子のシグネチャを一致させることができないため、隠蔽がどのように起こると思われますか? –

+1

@Alexei:静的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と表示され、aTypeAであり、bTypeBであるとします。コンパイラは、指定された大文字と小文字が一致する静的関数があるかどうかを調べるために、型TypeATypeB(および必要に応じてその親)に行きます。この場合、public static int op_Addition(TypeAOrBaseType a, TypeBOrBaseType b)である必要があります(operator +は、名前がop_Additionのメソッドにコンパイルされます)。それで、なぜ演算子を宣言するクラスが演算子の署名に参加すべきなのかはっきりするはずです - のようなものを宣言すると、TypeCTypeDを追加するとコンパイラは決して対応する演算子を探すことができないのでTypeAで - それはなぜでしょうか?それはTypeCTypeDになります。

  2. 通常の方法では、通常の方法ではシグネチャに任意の型を使用できますが、型宣言のインスタンスをシグネチャで使用する必要はありません(ただし、宣言のインスタンスメソッドインスタンス型は常に暗黙的に渡され、thisキーワードで使用できます)。

  3. 隠蔽は、親クラスと子クラスで全く同じシグネチャを持つ意味のある演算子を作るのが難しいため、演算子にはあまり意味がありません。コメントでは、そのような演算子(無駄なもの)を作ることはまだ可能ですが、それでも隠れていない場合でも、それらの演算子の1つを使用(子クラスまたは親クラスから選択する必要があります) )、代わりにコンパイラはあいまいさについて不平を言う。通常の方法では、隠蔽はしばしば有用であるため、許可されます。

関連する問題