2012-03-22 2 views
15

は、私は2つのタプルを定義するとしますタプルは==混乱

Tuple<float, float, float, float> tuple1 = new Tuple<float, float, float, float>(1.0f, 2.0f, 3.0f, 4.0f); 
Tuple<float, float, float, float> tuple2 = new Tuple<float, float, float, float>(1.0f, 2.0f, 3.0f, 4.0f); 

私はタプルを比較しようとすると、私は両方がtrueを返すために呼び出すために、私は期待と異なる結果

bool result1 = (tuple1 == tuple2); // FALSE 
bool result2 = tuple1.Equals(tuple2); // TRUE 

を取得します。 ==は正確に何ですか?

+0

http://msdn.microsoft.com/en-us/library/53k8ybth.aspx –

答えて

31

タプルの場合、==はオーバーロード==演算子ではないため、オブジェクト参照を比較しています。オブジェクトは同等ですが、同じ特定のインスタンスではないため、Equals()trueを返し、==falseを返します。

多くの種類のいくつかは、等価と参照平等のための==ためEquals()の区別を維持することを好む、==に過負荷をかけないでください。等価性のために==に頼るほか

は、いくつかのすごみにつながることができます:

public bool AreSame<T>(T first, T second) where T : class 
{ 
    return first == second; 
} 

コード上記の方法であれば、制約のない一般的なは、このように、コンパイル時にobject考えられるため、常に参照の等価性をチェックします仮想ではない場合は、stringなどのタイプが==をオーバーロードする場合でも、オブジェクトのバージョンを取得します。

したがって、上記のコードのこの使い方は:

var x = "Hello"; 
var y = "H"; 

// doing concat to avoid string interring 
AreSame(x, y+"ello"); 

はい、文字列が等価で、はいTstringですが、==はの==ジェネリックは拘束されないので、オブジェクトにバインドされ、これこれはfalseを返します。たとえ明示的なパラメータを持つ同じコードがtrueを返すとしても。

+0

私が想定していたおかげでその '=='と:推奨の方法は、のような何かを行うことです「等しい」は本質的に同じであった。私の混乱は、MSDNのオーバーロードガイドライン(http://msdn.microsoft.com/en-us/library/ms173147%28v=vs.80%29.aspx)から来ています。ここで '=='は単なる参照平等以外のものをチェックします。 – lumberjack4

+0

最高の経験則は、クラスのドキュメントをチェックして演算子==を実装しているかどうかを確認することです。同値チェックに 'Equals()'を使用することをお勧めします。等価性チェックを探しています。しかし、それは私です。 –

+0

AFAICT、AreSameはコンパイルさえしません。 "演算子 '=='は 'T'と 'T'型のオペランドには適用できません" – RobSiklos

9

==は、オブジェクト参照を比較しています。 Tupleクラスは==演算子にオーバーロードされないため、.Equalsを使用する必要があります。

+0

==演算子をオーバーライドするのはベストプラクティスですか?私はすべてを引き受けた。NETクラスは==演算子をオーバーライドします。 – lumberjack4

+0

'Tuple'は不変なので、このクラスは演算子をオーバーロードするのに適しているという合理的な議論ができるようです。しかし、私の経験では、この過負荷が 'DateTime'、' TimeSpan'などの 'string'や他の準基本的な型にあることを今までに予想していた唯一のクラスです。 –

9

==(タプル用)は参照のみが表示されるため、falseであることがわかります。

PS:

var tuple1 = Tuple.Create(1.0f, 2.0f, 3.0f, 4.0f) 
+0

' .0f '、それがなければ、コンパイラは' double to float conversion'エラーで叫んでいました... – bonCodigo

+2

そしてfを追加すると、 '.0'、つまり' 1f'、 '2f'などを削除できます。 – JotaBe