1. ホーム
  2. c#

[解決済み] C#のプリミティブの==とEquals()の違いは何ですか?

2022-04-20 09:02:22

質問

このコードを考えてみましょう。

int age = 25;
short newAge = 25;
Console.WriteLine(age == newAge);  //true
Console.WriteLine(newAge.Equals(age)); //false
Console.ReadLine();

両方 intshort はプリミティブ型ですが == との比較は真を返し Equals は偽を返します。

なぜ?

解決方法は?

簡単にお答えします。

平等は複雑です。

詳しい回答

プリミティブ型は、ベースとなる object.Equals(object) を返し、ボックス化された object が同じ タイプ と値を指定します。(これは nullable 型でも動作することに注意してください。null でない nullable 型は、常に基礎となる型のインスタンスに box します)。

以来 newAgeshort は、その Equals(object) メソッドは、ボックス化された 短い を同じ値で指定します。あなたが渡しているのは、箱型の int ということで、falseが返されます。

これに対して == 演算子は、2つの int を(または short または long s).

を付けて呼び出すと intshort の場合、コンパイラは暗黙のうちに shortint を実行し、結果の int を値で指定します。

その他の方法

プリミティブ型もまた、独自の Equals() メソッドで同じ型を受け取ります。

と書くと age.Equals(newAge) を選択し、コンパイラは int.Equals(int) を最適なオーバーロードとして、暗黙のうちに shortint . そして true というのは、このメソッドは単に int を直接指定します。

short もまた short.Equals(short) メソッドがありますが int に暗黙のうちに変換することはできません。 short ということで、呼んでいないのですね。

キャストでこのメソッドを強制的に呼び出すことができます。

Console.WriteLine(newAge.Equals((short)age)); // true

これは short.Equals(short) をボックス化せずに直接指定します。もし age が 32767 より大きい場合、オーバーフロー例外が発生します。

を呼び出すこともできます。 short.Equals(object) をオーバーロードして、明示的にボックス化されたオブジェクトを渡して、同じ型を取得するようにします。

Console.WriteLine(newAge.Equals((object)(short)age)); // true

前の選択肢と同様に、これは short . 前の解決策とは異なり、これは short をオブジェクトに変換し、時間とメモリを浪費しています。

ソースコード

ここでは、両方の Equals() メソッドを実際のソースコードから引用しています。

    public override bool Equals(Object obj) {
        if (!(obj is Int16)) {
            return false;
        }
        return m_value == ((Int16)obj).m_value;
    }

    public bool Equals(Int16 obj)
    {
        return m_value == obj;
    }

さらに読む

参照 エリック・リッパート .