しかし、うまくいかず、その理由がわかりません。
言語仕様がそう言っているからです。コンパイラは基本的にあなたに理由を与えています。
ロジックは良さそうですが、例の外で演算子オーバーロードを使用するのは初めてです。
メンバーの本体のロジックは問題ありませんが、任意の型の演算子をオーバーロードすることはできません。少なくとも 1 つのオペランド (または変換の戻り値の型) は、演算子を宣言する型である必要があります。
C# 5 仕様では、セクション 10.10 にこれが含まれています。
他のメンバーと同様に、基底クラスで宣言された演算子は派生クラスに継承されます。演算子の宣言では常に、演算子が宣言されているクラスまたは構造体が演算子のシグネチャに参加する必要があるため、派生クラスで宣言された演算子が、基底クラスで宣言された演算子を非表示にすることはできません。したがって、 new 修飾子は、演算子宣言では決して必要とされないため、決して許可されません。
そのルールは 10.10.1 で適用されます。
次の規則は、単項演算子の宣言に適用されます。ここで、T は、演算子の宣言を含むクラスまたは構造体のインスタンス型を示します。
- 単項 +、-、!、または ~ 演算子は、型 T または T? の単一のパラメーターを取る必要があります。任意の型を返すことができます。
- ...
.... 10.10.2:
次の規則は二項演算子宣言に適用されます。ここで、T は、演算子宣言を含むクラスまたは構造体のインスタンス型を示します。
- 二項非シフト演算子は 2 つのパラメーターを使用する必要があり、そのうちの少なくとも 1 つは T または T? 型である必要があり、任意の型を返すことができます。
- 二項演算子
<<
または>>
演算子は 2 つのパラメーターを取る必要があり、最初のパラメーターの型は T または T? でなければなりません。2 番目の型は int または int? である必要があり、任意の型を返すことができます。
...そして10.10.3:
特定のソース型 S とターゲット型 T について、S または T が null 許容型の場合、S0 と T0 はそれらの基になる型を参照します。それ以外の場合、S0 と T0 はそれぞれ S と T に等しくなります。クラスまたは構造体は、ソースの型 S からターゲットの型 T への変換を宣言できるのは、次のすべてが当てはまる場合のみです。
- S0 と T0 は異なるタイプです。
- S0 または T0 は、演算子の宣言が行われるクラスまたは構造体の型です。
- ...