C#では、違いは何ですか
Assert.AreNotEqual
と
Assert.AreNotSame
ここで与えられたほとんどすべての答えは正しいですが、おそらく例を挙げる価値があります:
public static string GetSecondWord(string text)
{
// Yes, an appalling implementation...
return text.Split(' ')[1];
}
string expected = "world";
string actual = GetSecondWord("hello world");
// Good: the two strings should be *equal* as they have the same contents
Assert.AreEqual(expected, actual);
// Bad: the two string *references* won't be the same
Assert.AreSame(expected, actual);
AreNotEqual
とはもちろんとのAreNotSame
反転です。AreEqual
AreSame
編集:現在受け入れられている回答への反論...
値の型で使用Assert.AreSame
する場合、それらはボックス化されます。つまり、次のことと同等です。
int firstNumber = 1;
int secondNumber = 1;
object boxedFirstNumber = firstNumber;
object boxedSecondNumber = secondNumber;
// There are overloads for AreEqual for various value types
// (assuming NUnit here)
Assert.AreEqual(firstNumber, secondNumber);
// ... but not for AreSame, as it's not intended for use with value types
Assert.AreSame(boxedFirstNumber, boxedSecondNumber);
は値型であるため、どちらfirstNumber
もsecondNumber
オブジェクト値を持ちませんint
。呼び出しが失敗する理由はAreSame
、.NET では、値をボックス化すると毎回新しいボックスが作成されるためです。(Java ではそうでない場合もあります - これは以前に私を捕まえました。)
基本的に、値の型を比較するときには絶対に使用しないでください。参照タイプをAreSame
比較するとき、同一の参照をチェックする場合に使用します。の下で等価性をチェックするために使用します。編集: NUnit が直接使用されない状況があることに注意してください。コレクション内の要素が等しいかどうかがテストされる、コレクションのサポートが組み込まれています。AreSame
AreEqual
Equals
Equals
回答の主張:
上記の例で int を string に変更すると、AreSame と AreEqual は同じ値を返します。
変数の初期化方法に完全に依存します。彼らが文字列リテラルを使用している場合、はい、インターンがそれを処理します。ただし、次を使用する場合:
string firstString = 1.ToString();
string secondString = 1.ToString();
その後AreSame
、AreEqual
ほぼ確実に同じ値を返しません。
はどうかと言うと:
一般的な経験則として、値型では AreEqual を使用し、参照型では AreSame を使用します。
参照の同一性を確認することはほとんどありません。私にとってはめったに役に立ちません。チェック対象である同等性をチェックしたいAreEqual
。(私はAreSame
それが存在すべきではないと言っているのではありません - それは有用な方法であり、AreEqual
.
2 つのものは等しい場合もありますが、オブジェクトは異なります。AreNotEqual は等価テストによってオブジェクトの値をチェックしますが、AreNotSame はオブジェクトがまったく同じではないことをチェックします。
物事が AreNotEqual であることをテストしたい理由は明らかです (テストされる値を気にします)。AreNotSameはどうですか?テストでのこれの有用性は、参照を渡し、シャッフルが完了した後も 2 つの参照が同じオブジェクトであることを確認したい場合に見つかります。
実際のケースでは、多くのキャッシュ オブジェクトを使用して、データベースへのラウンド トリップを軽減しています。オブジェクトがキャッシュ システムに渡された後、ユニット テストにより、場合によっては同じオブジェクトが返され (キャッシュが有効)、別の場合には新しいオブジェクトが返される (キャッシュが無効になった) ことが確認されます。この場合、AreNotEqual は必ずしも十分ではないことに注意してください。オブジェクトがデータベースに新しいタイムスタンプを持っていても、データが同等性テストに失敗するほど「十分に異なっていない」場合、AreNotEqual はオブジェクトを更新したことに気付かないでしょう。
AreNotSameは参照比較を行いますが、 AreNotEqualは等価比較を行います。
Assert.AreNotEqual は、2 つの値が互いに等しくないことをアサートします。
Assert.AreNotSame は、2 つの変数が同じオブジェクトを指していないことを表明します。
例 1:
int i = 1; int j = i; // 値は等しい: Assert.AreEqual(i, j); // 2 つの値の型は同じオブジェクトを表していません: Assert.AreNotSame(i, j);
例 2:
文字列 s = "A"; 文字列 t = s; // 値は等しい: Assert.AreEqual(s, t); // 参照型は同じオブジェクトを指すことができます: Assert.AreSame(s, t);
AreNotSame は参照の等価性 ( object.ReferenceEquals
) を使用します。つまり、それらはオブジェクトの実際のインスタンスと同じです。AreNotEqual は、概念的な等価性 ( .Equals
) を使用します。つまり、それらは等しいと見なされます。
AreNotEqual は 2 つのオブジェクトが Equals() メソッドに関して等しくない場合をチェックするのに対し、AreNotSame は 2 つのオブジェクト参照が同じでない場合をチェックするのではないでしょうか。したがって、x と y が Equals() に関して等しいが別々に割り当てられた 2 つのオブジェクトである場合、AreNotEqual() は失敗したアサーションをトリガーしますが、もう一方はトリガーしません。