C#での値の比較方法である、「==」関係演算子と、Equalsメソッド、ReferenceEqualsメソッドの違いと使い分けについて紹介します。
サンプルコード
using System;
using System.Text;
class EqualityRelationSample
{
static void Main(string[] args)
{
var sb1 = new StringBuilder("ABC");
var sb2 = new StringBuilder("ABC");
Console.WriteLine(sb1 == sb2); //False
Console.WriteLine(sb1.Equals(sb2)); //True
Console.WriteLine(Object.ReferenceEquals(sb1, sb2)); //False
int num1 = 123;
int num2 = 123;
string word1 = "123";
Console.WriteLine(num1 == num2); //True
Console.WriteLine(num1.Equals(num2)); //True
Console.WriteLine(Object.ReferenceEquals(num1, num2)); //False
//Console.WriteLine(num1 == word1); //エラー(CS0019)
Console.WriteLine(num1.Equals(word1)); //False
}
}
同一性の比較と同値性の比較
比較には、同一性(Identity)の比較と同値性(Equivalence)の比較があり、これらの違いを理解することが使い分けの重要なポイントとなります。
同一性の比較
オブジェクトの参照が同一であること(=同じメモリアドレスを参照していること)。
同値性の比較
オブジェクトの持つ値が同一であること。
この比較方法の違いにより、比較結果が異なります。
補足
「==」演算子、Equalsメソッドともに、既定は同一性の比較です。
値型の場合は、値を直接格納するため、同一性の比較は意味をなしません(必ずFalseになります)。
「==」演算子での比較
同一性の比較となる場合
- ミュータブルな参照型(値の変更が可能な参照型)
同値性の比較となる場合
- 値型
- イミュータブルな参照型(値の変更ができない参照型)
また、異なる型の場合はコンパイルエラー(CS0019)となります。
Equalsメソッドでの比較
同一性・同値性の比較パターンは「==」メソッドとほぼ同様です。
但し、一部のミュータブルな参照型は同値性の比較となります。
また、異なる型であってもコンパイルエラーとなりません。
ReferenceEqualsメソッドでの比較
同一性の比較となります。
※RefarenceEqualsメソッドは、オーバーライドできません。
両者の使い分け
- 値型は「==」演算子を使用する。
- イミュータブルな参照型(Stringオブジェクトなど)の同値性を比較したい場合は「==」演算子を使用する
- ミュータブルな参照型(StringBuilderオブジェクトなど)で同値性を比較する場合はEqualsメソッドを使用する。
- 同一性の比較を行いたい場合は、ReferenceEqualsメソッドを使用する。
使い分けの補足
同値性の比較の場合は、「==」演算子の方が型の不一致でエラーとなるため、優先的に使用する方が良いかと思います。
しかし、実装により同一性の比較となる場合があるため、参照型の同一性を比較したい場合はReferenceEqualsメソッドを使用し、同値性を比較したい場合はEqualsメソッドを使用する方法でも良いかもしれません。
(実装を知り、使い分けられることが理想ではあります)
同値性の比較ルールはクラス(オブジェクト)によって異なりますが、 まずは、オブジェクト(参照型)はEqualsメソッドによって比較する、と覚えておいてください。
山田 祥寛. 独習C# 新版. 株式会社 翔泳社.