Object.Equals メソッド (Object)
指定した Object が、現在の Object と等しいかどうかを判断します。
Overloads Public Overridable Function Equals( _
ByVal obj As Object _) As Boolean
[C#]
public virtual bool Equals(objectobj);
[C++]
public: virtual bool Equals(Object* obj);
[JScript]
public function Equals(
obj : Object) : Boolean;
パラメータ
- obj
現在の Object と比較する Object 。
戻り値
指定した Object が現在の Object と等しい場合は true 。それ以外の場合は false 。
解説
Equals の既定の実装では、参照を等価にする機能だけがサポートされています。ただし、派生クラスでこのメソッドをオーバーライドすると、値を等価にする機能をサポートできます。
参照型の等価とは、参照先オブジェクトが等しい場合、つまり同一オブジェクトを参照している参照の関係です。値型の等価とは、2 つの値がビット単位で等しい状態です。 ValueType クラスは値型をサポートします。
実装時の注意:
このメソッドは、派生クラスでオーバーライドできます。たとえば、両方のオブジェクトが同じ値を参照している場合、基本データ型は true を返します。それ以外の場合は false を返します。
このメソッドは、プリミティブとオブジェクトだけを比較します。オブジェクト配列などの複雑な構造体を比較するには、このメソッドをオーバーライドする必要があります。
次に示すステートメントは、 Equals メソッドのすべての実装に対し true である必要があります。リストの x、y、および z は、 null 参照 (Visual Basic では Nothing) ではないオブジェクト参照を表します。
- x.Equals(x) は、浮動小数点型が関連する場合を除き、 true を返します。IEC 60559:1989, Binary Floating-point Arithmetic for Microprocessor Systems を参照してください。
- x.Equals(y) は y.Equals(x) と同じ値を戻します。
- x.Equals(y) は、x と y が両方とも NaN である場合に true を返します。
- (x.Equals(y) && y.Equals(z)) は、x.Equals(z) が true を返す場合に限り、 true を返します。
- x.Equals(y) を連続して呼び出す場合、x と y が参照するオブジェクトが変更されていない限り、同じ値が返されます。
- x.Equals(null 参照 (Nothing)) は false を返します。
Equals メソッドに関するその他の必須動作については、 GetHashCode メソッドのトピックを参照してください。
Equals の実装が例外がスローすることはありません。
オブジェクトによっては、参照が等価なのではなく、値が等価であることを Equals でテストする必要があります。このような Equals の実装では、この 2 つのオブジェクトの "値" が同一である場合、インスタンスが異なる場合でも true が返されます。型のインプリメンタが、オブジェクトの "値" を構成するデータを決定します。通常、これはオブジェクトのインスタンス変数に格納されているデータの一部または全体です。たとえば、 String の値は文字列の文字に基づいています。 String クラスの Equals メソッドは、同じ文字が同じ順序で格納されている 2 つの文字列インスタンスに対し、 true を返します。
IComparable を実装する型は、 Equals をオーバーライドする必要があります。
Equals をオーバーライドする型は、 GetHashCode もオーバーライドする必要があります。このようにオーバーライドしないと、 Hashtable が適切に機能しません。
使用するプログラミング言語で演算子をオーバーロードできる場合に、特定の型について等値演算子をオーバーロードするには、その型で Equals メソッドをオーバーライドする必要があります。このような Equals メソッドの実装では、等値演算子を使用した場合と同じ結果を返す必要があります。 Equals (ArrayList および Hashtable など) を使用するクラス ライブラリ コードが、アプリケーション コードにより等値演算子が使用される方法と矛盾しない方法で動作するように実装するためのガイドラインを次に示します。
次のガイドラインは、値型の実装のためのものです。
- ValueType での Equals の既定の実装よりも高いパフォーマンスを引き出すには、 Equals のオーバーライドを考慮してください。
- プログラミング言語で演算子をオーバーロードできる場合に、 Equals をオーバーライドするには、値型の等値演算子をオーバーロードする必要があります。
参照型の実装のためのガイドラインを次に示します。
- 参照型のセマンティクスが、その型がなんらかの値を表しているという事実に基づいている場合には、この参照型の Equals のオーバーライドを検討してください。
- ほとんどの参照型では、 Equals をオーバーライドする場合でも、等値演算子はオーバーロードしないでください。ただし、複素数型のような、値のセマンティクスを持つ参照型を実装する場合には、等値演算子をオーバーライドする必要があります。
使用例
現在のインスタンスと他のオブジェクトを比較するコード例を次に示します。
Imports System
Public Class Sample
Sub Method()
Dim Obj1 As New Object()
Dim Obj2 As New Object()
Console.WriteLine(Obj1.Equals(Obj2)) '===> false
Obj2 = Obj1
Console.WriteLine(Obj1.Equals(Obj2)) '===> true
End Sub 'Method
End Class 'Sample
[C#]
using System;
public class Sample {
void Method() {
Object Obj1 = new Object();
Object Obj2 = new Object();
Console.WriteLine(Obj1.Equals(Obj2)); //===> false
Obj2 = Obj1;
Console.WriteLine(Obj1.Equals(Obj2)); //===> true
}
}
[C++]
#using <mscorlib.dll>
#using <System.DLL>
using namespace System;
__gc class Sample
{
void Method()
{
Object *Obj1 = new Object();
Object *Obj2 = new Object();
Console::WriteLine(Obj1->Equals(Obj2)); //===> false
Obj2 = Obj1;
Console::WriteLine(Obj1->Equals(Obj2)); //===> true
}
};
次に示す例では、 Equals メソッドをオーバーライドして値が等価であることを実現する Point クラスと、 Point から派生した Point3D クラスを示します。 Point による Equals のオーバーライドが、値が等価であることを導入するための継承チェインで最初に発生するため、基本クラスの Equals メソッド (Object から継承され、参照が等価かどうかをチェックするメソッド) は呼び出されません。ただし、 Equals の実装により Point が値が等価であることを実現するため、 Point3D.Equals は Point.Equals を呼び出します。
using System;
class Point: Object {
protected int x, y;
public Point() {
this.x = 0;
this.y = 0;
}
public Point(int X, int Y) {
this.x = X;
this.y = Y;
}
public override bool Equals(Object obj) {
//Check for null and compare run-time types.
if (obj == null || GetType() != obj.GetType()) return false;
Point p = (Point)obj;
return (x == p.x) && (y == p.y);
}
public override int GetHashCode() {
return x ^ y;
}
}
class Point3D: Point {
int z;
public Point3D(int X, int Y, int Z) {
this.x = X;
this.y = Y;
this.z = Z;
}
public override bool Equals(Object obj) {
return base.Equals(obj) && z == ((Point3D)obj).z;
}
public override int GetHashCode() {
return base.GetHashCode() ^ z;
}
}
[C++]
#using <mscorlib.dll>
using namespace System;
__gc class Point: public Object {
protected:
int x, y;
public:
Point() {
this->x = 0;
this->y = 0;
}
Point(int X, int Y) {
this->x = X;
this->y = Y;
}
bool Equals(Object* obj) {
//Check for null and compare run-time types.
if (obj == 0 || GetType() != obj->GetType()) return false;
Point* p = dynamic_cast<Point*>(obj);
return (x == p->x) && (y == p->y);
}
int GetHashCode() {
return x ^ y;
}
};
__gc class Point3D: public Point {
int z;
public:
Point3D(int X, int Y, int Z) {
this->x = X;
this->y = Y;
this->z = Z;
}
bool Equals(Object* obj) {
return Point::Equals(obj) && z == (dynamic_cast<Point3D*>(obj))->z;
}
int GetHashCode() {
return Point::GetHashCode() ^ z;
}
};
[JScript]
import System;
import System.Drawing
class Point extends Object {
var x : int;
var y : int;
public override function Equals(obj : Object) : Boolean {
//Check for null and compare run-time types.
if (obj == null || GetType() != obj.GetType()){
return false;
}
var p : Point = Point(obj);
return (x == p.x) && (y == p.y);
}
public override function GetHashCode() : int {
return x ^ y;
}
}
class Point3D extends Point {
var z : int;
public override function Equals(obj : Object) : Boolean{
return super.Equals(obj) && z == (Point3D(obj)).z;
}
public override function GetHashCode() : int {
return super.GetHashCode() ^ z;
}
}
Point.Equals メソッドは、 obj 引数が null 参照 (Visual Basic では Nothing) ではないことと、このオブジェクトと同じ型のインスタンスを参照していることを確認します。いずれかの確認が失敗すると、このメソッドは false を返します。
Equals メソッドは、 GetType を使用して、2 つのオブジェクトのランタイム型が同一かどうかを判断します。 typeof は静的な型を返すため、使用されない点に注意してください。メソッドが形式 obj is Point
のチェックを使用する場合、 obj が Point の派生クラスのインスタンスであれば、 obj と現在のインスタンスのランタイム型が同一でなくても、 true が返されます。2 つのオブジェクトの型が同一であることが検証されると、このメソッドは obj を Point 型にキャストし、2 つのオブジェクトのインスタンス変数を比較した結果を返します。
Point3D.Equals では、継承した Equals メソッドが最初に呼び出されます。継承した Equals メソッドは、 obj が null 参照 (Nothing) ではないこと、 obj がこのオブジェクトと同じクラスのインスタンスであること、および継承されたインスタンス変数が一致することを確認します。継承された Equals が true を返す場合だけ、このメソッドは派生クラスに導入されているインスタンス変数を比較します。特に、 obj が Point3D 型であるか、または Point3D の派生クラスであることが確認されていない場合は、 Point3D へのキャストは実行されません。
前述の例では、 operator == (等値演算子) を使用して各インスタンス変数が比較されています。場合によっては、次のコード例に示すように、 Equals メソッドを使用し、 Equals 実装でインスタンス変数を比較する方が適切です。
using System;
class Rectangle {
Point a, b;
public Rectangle(int upLeftX, int upLeftY, int downRightX, int downRightY) {
this.a = new Point(upLeftX, upLeftY);
this.b = new Point(downRightX, downRightY);
}
public override bool Equals(Object obj) {
// Performs an equality check on two rectangles (Point object pairs).
if (obj == null || GetType() != obj.GetType()) return false;
Rectangle r = (Rectangle)obj;
//Uses Equals to compare variables.
return a.Equals(r.a) && b.Equals(r.b);
}
public override int GetHashCode() {
return a.GetHashCode() ^ b.GetHashCode();
}
}
[C++]
__gc class Rectangle {
Point* a;
Point* b;
public:
Rectangle(int upLeftX, int upLeftY, int downRightX, int downRightY) {
this->a = new Point(upLeftX, upLeftY);
this->b = new Point(downRightX, downRightY);
}
bool Equals(Object* obj) {
// Performs an equality check on two rectangles (Point object pairs).
if (obj == 0 || GetType() != obj->GetType()) return false;
Rectangle* r = dynamic_cast<Rectangle*>(obj);
//Uses Equals to compare variables.
return a->Equals(r->a) && b->Equals(r->b);
}
int GetHashCode() {
return a->GetHashCode() ^ b->GetHashCode();
}
};
[JScript]
import System;
import System.Drawing;
class Rectangle {
var a : Point;
var b : Point;
public override function Equals(obj : Object) : Boolean {
if (obj == null || GetType() != obj.GetType()) {
return false;
}
var r : Rectangle = Rectangle(obj);
//Uses Equals to compare variables.
return a.Equals(r.a) && b.Equals(r.b);
}
public override function GetHashCode() : int {
return a.GetHashCode() ^ b.GetHashCode();
}
}
C# などの一部の言語では、演算子をオーバーロードできます。 operator == をオーバーロードする型は、 Equals メソッドもオーバーライドして、同様の機能を提供する必要があります。通常、この処理を記述するには、次のコード例に示すように、オーバーロードした operator == を使用して Equals メソッドを記述します。
using System;
public struct Complex {
public double re, im;
public override bool Equals(Object obj) {
return obj is Complex && this == (Complex)obj;
}
public override int GetHashCode() {
return re.GetHashCode() ^ im.GetHashCode();
}
public static bool operator ==(Complex x, Complex y) {
return x.re == y.re && x.im == y.im;
}
public static bool operator !=(Complex x, Complex y) {
return !(x == y);
}
}
[C++]
#using <mscorlib.dll>
using namespace System;
public __value struct Complex {
double re, im;
bool Equals(Object* obj) {
return dynamic_cast<Complex*>(obj) && *this == *dynamic_cast<Complex*>(obj);
}
int GetHashCode() {
return re.GetHashCode() ^ im.GetHashCode();
}
static bool op_Equality(Complex x, Complex y) {
return x.re == y.re && x.im == y.im;
}
static bool op_Inequality(Complex x, Complex y) {
return !(x == y);
}
};
Complex は C# 構造体 (値型) であるため、他のクラスから派生させることはできません。したがって、 Equals メソッドが各オブジェクトの GetType の結果を比較する必要はありません。このメソッドは、 is 演算子を使用して obj パラメータの型を確認できます。
必要条件
プラットフォーム: Windows 98, Windows NT 4.0, Windows Millennium Edition, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 ファミリ, .NET Compact Framework - Windows CE .NET, Common Language Infrastructure (CLI) Standard
参照
Object クラス | Object メンバ | System 名前空間 | Object.Equals オーバーロードの一覧 | ReferenceEquals | GetHashCode | ValueType | IComparable | System.Collections.ArrayList | System.Collections.Hashtable