이번 포스팅에서는 C#에서 Equals() 함수를 재정의해야 하는 이유에 대해 소개합니다.
Equals() 함수와 == 연산자의 차이
C#의 자료형에 대해 공부하신 분들은 아시겠지만, C#에서 모든 자료형은 Object 클래스에서 직접 또는 간접적으로 상속됩니다. Object 클래스에는 Equals()
함수가 존재하는데, 모든 자료형은 Object 클래스에서 파생되므로 Equals()
함수를 사용할 수 있습니다.
다음은 ==
연산자와 Equals()
함수를 사용하는 예제입니다.
int a = 10;
int b = 10;
Console.WriteLine(a == b);
// true
Console.WriteLine(a.Equals(b));
// true
Console.WriteLine(b.Equals(a));
// true
변수 a
와 b
는 동일한 값을 가지므로 true를 반환합니다.
기본 자료형이 아닌 참조 형식인 경우 ==
연산자는 참조가 동일한지 확인하며, Equlas()
함수는 값이 동일한지 확인합니다. 다음은 참조 형식인 클래스 인스턴스에 ==
연산자와 Equals()
함수를 사용하는 예제입니다.
class Program
{
static void Main(string[] args)
{
Person person1 = new Person();
person1.Name = "Ham";
person1.Age = 30;
Person person2 = person1;
Console.WriteLine(person1 == person2);
// true
Console.WriteLine(person1.Equals(person2));
// true
Console.WriteLine(person2.Equals(person1));
// true
}
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
참조 형식인 클래스는 Call-By-Reference 구조입니다. 참조 변수인 peson1
과 peson2
는 스택(Stack)에 생성되지만, 실제 값은 힙(Heap)에 저장된 객체를 가리킵니다.
반면에 다음 예제는 false를 반환합니다.
class Program
{
static void Main(string[] args)
{
Person person1 = new Person();
person1.Name = "Ham";
person1.Age = 30;
Person person2 = new Person();
person2.Name = "Ham";
person2.Age = 30;
Console.WriteLine(person1 == person2);
// false
Console.WriteLine(person1.Equals(person2));
// false
Console.WriteLine(person2.Equals(person1));
// false
}
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
person1
과 person2
는 힙에 서로 다른 객체를 참조하고 있으므로 ==
연산자에서 false를 반환합니다. Equlas()
함수는 person1
과 person2
가 값이 동일함에도 false를 반환합니다. 따라서, 참조 형식에서 값이 같을 때 true를 반환하도록 Equlas()
함수를 재정의해야 합니다.
Equals() 함수 재정의 방법
다음 예제는 Equals()
함수를 재정의합니다. 객체가 null이 아닌지 체크하고 해당 클래스 형식으로 변환 가능한지 체크합니다. 그리고 Equals()
함수를 재정의하는 경우 GetHashCode()
함수도 재정의해야 합니다.
class Program
{
static void Main(string[] args)
{
Person person1 = new Person();
person1.Name = "Ham";
person1.Age = 30;
Person person2 = new Person();
person2.Name = "Ham";
person2.Age = 30;
Console.WriteLine(person1 == person2);
// false
Console.WriteLine(person1.Equals(person2));
// true
Console.WriteLine(person2.Equals(person1));
// true
}
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (!(obj is Person))
{
return false;
}
return (this.Name == ((Person)obj).Name)
&& (this.Age == ((Person)obj).Age);
}
public override int GetHashCode()
{
return Name.GetHashCode() ^ Age.GetHashCode();
}
}
'C#' 카테고리의 다른 글
[C#]콘솔(Console) 입력 및 출력 (0) | 2022.01.09 |
---|---|
[C#]ToString 재정의 (0) | 2022.01.09 |
[C#]Convert.ToString()과 ToString() 차이 (1) | 2022.01.09 |
[C#]checked, unchecked 키워드 (0) | 2021.12.29 |
[C#]정적 멤버(static member), 비정적 멤버(Non-static member) (2) | 2021.12.25 |
댓글