web-dev-qa-db-ja.com

C#は2つの一般的な値を比較します

可能性のある複製:
演算子==はC#のジェネリック型に適用できませんか?

私はこのようなものをコーディングしました:

public bool IsDataChanged()
{           
    T value1 = GetValue2;
    T value2 = GetValue1();

    return (valueInDB != valueFromView);
}

現在、関数は「演算子 '!='はタイプ 'T'および 'T'のオペランドに適用できません」というエラーでコンパイルされません。この機能を動作させるにはどうすればよいですか?

67
bernhardrusch

T:クラスが参照型であることを示すためにクラスを追加しない限り、foo == nullは例外です)

EqualityComparer<T>。Defaultを使用してそれを実行します。これは、not ==の演算子オーバーロードのみを提供するタイプでも機能します。

  • IEquatable<T>を実装する
  • object.Equals()をオーバーライドします

一般に==演算子を実装し、これらの少なくとも1つを実行しないことは、とにかく非常に悪い考えであるため、これは問題になる可能性はありません。

public bool IsDataChanged<T>()
{           
    T value1 = GetValue2;
    T value2 = GetValue1();

    return !EqualityComparer<T>.Default.Equals(value1 , value2);
}

IEquatable<T>に制限しない場合、EqualityComparerのデフォルトフォールバックは、IEquatable<T>を実装していない場合、値型で使用するとボクシングを引き起こす可能性があります(使用する型を制御する場合、これは重要ではありません)。 =!を使用していたと仮定しています。ただし、パフォーマンスのために、Genericタイプに制限すると、Object.Equals(object)ルートを介した偶発的ボクシングが回避されます。

120
ShuggyCoUk

それはあなたのために働くはずです。

public bool test<T>(T test, T test2) where T : class
{
    return (test != test2);
}

これは、質問にコメントした例から単に貼り付けられています。

4
CalvinR

あなたの型は IComparable または IEquatable インターフェースを実装する必要があります。

おそらく、a!= bを!(a == b)に書き換えるか、CompareTo()またはEquals()メソッドを明示的に呼び出す必要があります。

3
devio

オブジェクトの.Equals()メソッドをオーバーロードして、評価を次のように変更できます。

return (!valueInDB.Equals(valueFromView));

ValueInDBとvalueFromViewがオブジェクトであると仮定します。サンプル変数の名前は、比較で使用したものと同じではないため、仮定しなければなりませんでした。

編集:3秒でビートを得ました!オーバーロードに関する注意。型内の値を比較する必要がある場合、Object型の基本的な.Equals()は、複雑な型のメモリ比較のみを行うため、十分ではありません。オブジェクトを比較する方法の実装をオーバーロードして提供する必要があります。

0
Jay S