この方法は有効だと思いましたが、間違っていました:
static void Equals<T>(T x, T y)
{
return x == y; //operator == can't be applied to type T
}
仕様を読んだ後 (v3.0 では §7.2.4、v4.0 では §7.3.4):
7.2.4 二項演算子のオーバーロード解決
x op y という形式の演算 (op はオーバーロード可能な二項演算子、x は X 型の式、y は Y 型の式) は、次のように処理されます。
演算演算子 op(x, y) に対して X および Y によって提供される候補ユーザー定義演算子のセットが決定されます。セットは、X によって提供される候補演算子と Y によって提供される候補演算子の和集合で構成され、それぞれが §7.2.5 の規則を使用して決定されます。X と Y が同じ型である場合、または X と Y が共通の基本型から派生している場合、共有候補演算子は組み合わせセットで 1 回だけ出現します。
候補のユーザー定義演算子のセットが空でない場合、これが操作の候補演算子のセットになります。それ以外の場合は、事前定義された二項演算子 op の実装 (持ち上げられた形式を含む) が、演算の候補演算子のセットになります。特定の演算子の事前定義された実装は、演算子の説明で指定されます (§7.7 から §7.11)。
§7.4.3 のオーバーロード解決規則が候補演算子のセットに適用され、引数リスト (x, y) に関して最適な演算子が選択され、この演算子がオーバーロード解決プロセスの結果になります。オーバーロードの解決で最適な演算子を 1 つ選択できなかった場合、コンパイル時エラーが発生します。
ステップ 2 では、この定義済みの実装を適用する必要があると思います。
bool operator ==(object x, object y);
bool operator !=(object x, object y);
C# ではすべてが Object から派生しているためです。手順 3 でコンパイル時エラーが発生するのはなぜですか? この場合、「過負荷の解決が選択に失敗する」可能性はないと思います。
編集次のようなものを実装していたときに、この質問が頭に浮かびました。
class EnumComparer<TEnum> : IEqualityComparer<TEnum>
{
public bool Equals(TEnum x, TEnum y)
{
return x == y;
}
public int GetHashCode(TEnum obj)
{
return (int)obj;
}
}
残念ながら、式を作成してメソッドで動的に呼び出す必要がありEquals
ます。