質問

この方法は有効だと思いましたが、私は間違っていました:

static void Equals<T>(T x, T y)
{
    return x == y;    //operator == can't be applied to type T
}

指定を読んだ後(v3.0の§7.2.4および§7.3.4in v4.0):

7.2.4バイナリ演算子過負荷解像度

opは過負荷可能なバイナリ演算子であり、xはタイプxの式であり、yはタイプyの式であり、次のように処理されます。

  • Operation Operator 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)に関して最適なオペレーターを選択し、この演算子が過負荷解像度プロセスの結果になります。過負荷解像度が単一の最高の演算子を選択できない場合、コンパイル時間エラーが発生します。

ステップ2では、この事前定義された実装を適用する必要があると思います。

bool operator ==(object x, object y);
bool operator !=(object x, object y);

C#のすべてがオブジェクトに由来するためです。ステップ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 方法。

役に立ちましたか?

解決

スペックを読んでくれていいのですが、すぐに読むのをやめました。さらに読んでいたら、このビットに到達していたでしょう。


事前定義された参照タイプの平等演算子には、次のいずれかが必要です。

  • 両方のオペランドは、参照型またはリテラルヌルであることが知られているタイプの値です。さらに、いずれかのオペランドのタイプから他のオペランドのタイプまで、明示的な参照変換が存在します。

  • 1つのオペランドはタイプTの値で、tはタイプパラメーターであり、もう1つのオペランドはリテラルヌルです。さらに、Tには値タイプの制約がありません。

これらの条件のいずれかが真でない限り、結合時間エラーが発生します。 (*)


エラーは過負荷解像度によるものではありません。エラーは、過負荷解像度が事前に定義された参照型等式演算子を選択し、参照タイプがないことです。

コードを検討してください。 Tが等式オペレーターが定義されていない値タイプであることを妨げるものは何ですか?何もない。オブジェクトバージョンに戻ったとします。どちらのオペランドも異なる場所にボックスをかけ、したがって、たとえ同じコンテンツを持っていても、参照事実です。それは遅く、混乱し、間違っているので、試すことさえ違法です。

そもそもなぜこのことをしようとしているのですか?あなたの方法が機能しなかった場合、そうでない場合、あなたの方法は 悪い そもそも==を使用するよりも。この方法で世界に追加する価値は何ですか?


(*)この文の文法誤差は、仕様メンテナーに報告しました。

他のヒント

それがそれを知っていれば、それはおそらくうまくいくでしょう where T : class, 、参照比較を行う。一般に、オペレーターはジェネリックではほとんどサポートされていませんが、回避策があります。 Miscutilオファー オペレーターの間接的なサポート それ以外の場合はジェネリックについて EqualityComparer<T>.Default.Equals(x,y) 良い選択です。

私は使うのが好きです EqualityComparer<T>.Default このため。

オーバーライドされたものに基づいています Equals メソッドですが、使用します IEquatable<T> 利用可能な場合は、それを実装する値タイプのボクシングを避けます。

EqualityComparer<T>.Default.Equals(x, y)

使用する .Equals() 方法とそれを確認してください T 埋め込む IComparable

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top