우리는 개발을 하다보면 객체의 같음을 비교할 때가 많다. 실제 참조가 같은지 혹은 사용자가 만든 객체의 특정 값이 같은지를 비교하여 참 값을 구하고 싶을 때를 얘기하는 것이다. 지금 작성하는 코드는 실제 MSDN에서 형식에 대한 값 같음을 정의하는 방법이라는 제목으로 올라와 있는 패턴이다.
사용자 객체는 IEquatable를 상속받아 인터페이스 Equals(T)를 정의하고 object 객체의 가상함수인 Equals(object)와 GetHashCode()를 override한다. 그리고 마지막으로 operator==, operator≠를 정의한다.
GetHashCode는 해시 테이블과 같은 키 값을 갖는 자료구조에서 객체를 관리하고 싶을 때 쓰이는 키인데 실제로 반환값이 어떻게 발생하는지 과연 키 값으로써 유효한지 모르겠다. 확률적으로 희박한 것인지. 실제로 이 값을 키로 써본적이 없어 추후 따로 다뤄야 할 것 같다.
다음 예제는 Person이라는 사람객체는 이름, 나이, 고유 아이디값을 갖고 고유 아이디값과 같음을 비교해 같으면 true 다르면 false를 반환하겠다.
public Person(string name, int age, string personalId)
{
Name = name;
Age = age;
PersonalId = personalId;
}
public string Name { get; private set; }
public int Age { get; private set; }
public string PersonalId { get; private set; }
public bool Equals(Person other)
{
if (other is null)
return false;
if (object.ReferenceEquals(this, other))
return true;
return this.PersonalId == other.PersonalId;
}
public override bool Equals(object obj)
{
return this.Equals(obj as Person);
}
public static bool operator== (Person left, Person right)
{
if(left is null)
{
if (right is null)
return true;
return false;
}
return left.Equals(right);
}
public static bool operator !=(Person left, Person right)
{
return !(left == right);
}
public override int GetHashCode()
{
return base.GetHashCode() ^ this.PersonalId.GetHashCode();
}
public override string ToString()
{
return $"이름: {this.Name} 나이: {this.Age} 아이디: {this.PersonalId}";
}
class Program
{
static void Main(string[] args)
{
List<Person> people = new List<Person>()
{
new Person("이은혜", 31, "2"),
new Person("안광필", 35, "3"),
new Person("최용국", 28, "1"),
new Person("이정선", 29, "4")
};
Person targetPerson = new Person("도로시", 1, "1");
foreach(var person in people)
{
if(person == targetPerson)
Console.WriteLine($"같아요!! target: {targetPerson} source: {person} ");
else
Console.WriteLine($"때앵 달라요!! target: {targetPerson} source: {person} ");
}
Console.Read();
}
}