IEqualityComparer<T> 인터페이스
IEqualityComparer 인터페이스
namespace System.Collections
{
public interface IEqualityComparer
{
bool Equals(object x, object y);
int GetHashCode(object obj);
}
}
EqualityComparer<T> 클래스
namespace System.Collections.Generic
{
public abstract class EqualityComparer<T> : IEqualityComparer, IEqualityComparer<T>
{
protected EqualityComparer();
public static EqualityComparer<T> Default { get; }
public abstract bool Equals(T x, T y);
public abstract int GetHashCode(T obj);
}
}
- 기본 방식 이외의 상등 비교나 해시 계산 구현을 위한 상등 비교자(Equality Comparer)를 만드는데 사용 됨
- 주로 Dictionary 클래스와 Hashtable 클래스에 유용
- 해시테이블 기반 사전들의 요구 사항
* 해당 키와 같은(상등하는) 키의 존재 여부
* 해당 키의 정수 해시코드
- 상등 비교자를 작성할 때에는 제네릭, 비제네릭 인터페이스 중 하나, 혹은 둘 다를 구현
- 두개를 다 구현하기 귀찮다면 EqualityComparer 클래스를 상속받아서 한번에 처리
- 커스텀 상등자를 이용한 비교
using System;
using System.Collections.Generic;
namespace Practice
{
class Program
{
public static void Main(string[] arg)
{
Customer c1 = new Customer("Jaina", "Proudmoore");
Customer c2 = new Customer("Jaina", "Proudmoore");
// 기본적 참조 상등 의미론 적용
Console.WriteLine(c1 == c2); // false
Console.WriteLine(c1.Equals(c2)); // false
// Dictionary에서의 상등 비교(키 값 검색)
var dic1 = new Dictionary<Customer, string>();
dic1[c1] = "the Archmage";
Console.WriteLine(dic1.ContainsKey(c2)); // false
// 커스텀 상등 비교자를 이용한 상등 비교
var cnec = new CustomerNameEqualityComparer();
var dic2 = new Dictionary<Customer, string>(cnec);
dic2[c1] = "the Archmage";
Console.WriteLine(dic2.ContainsKey(c2)); // true
}
}
public class Customer
{
public string LastName { get; set; }
public string FirstName { get; set; }
public Customer (string last, string first)
{
LastName = last;
FirstName = first;
}
}
public class CustomerNameEqualityComparer : EqualityComparer<Customer>
{
public override bool Equals(Customer x, Customer y)
{
return (x.LastName == y.LastName) && (x.FirstName == y.FirstName);
}
public override int GetHashCode(Customer obj)
{
return $"{obj.LastName};{obj.FirstName}".GetHashCode();
}
}
}
- 위 예에서 고객이 사전에 담겨있을 때, 고객의 FirstName과 LastName이 수정되지 않도록 조치해야 한다고 한다.
그런 장치가 없다면 고객의 해시코드가 변해서 Dictionary가 오작동 할 수 있다고 한다.
- 책에 나온 내용이 저게 다라서 오작동 하는 정확한 이유를 모르겠는데...
아마 해시코드를 기반으로한 위치에 자료를 저장해놓는데,
키 값이 변하면서 해쉬코드도 변해버리면 바뀐 곳으로 접근하고
그 이전에 저장했던(바뀌기 전의 해쉬코드) 곳으로 접근하지 못하게 되서 그런게 아닐까 싶다.
공부가 더 필요하다.
EqualityComparer<T>.Defalut 메서드
- static object.Equals 메서드 대신 사용 할 수 있는 범용 상등 비교자를 반환
- 먼저 T가 IEquatable<T>를 구현하는지 점검해서, 구현 한다면 사용하므로 박싱 부담이 없음
- 제네릭 메서드에서 특히 유용
static bool Foo<T>(T x, T y)
{
return EqualityComparer<T>.Default.Equals(x, y);
}
'C#' 카테고리의 다른 글
[C#] IDisposable (Dispose), 종료자(Finalizer) (0) | 2023.10.10 |
---|---|
[C#] IStructuralEquatable, IStructuralComparable (0) | 2023.10.08 |
[C#] StringComparer (0) | 2023.10.06 |
[C#] IComparer<T>, IComparer, Comparer<T> (0) | 2023.10.04 |
[C#] KeyedCollection<TKey,TItem>, DictionaryBase (0) | 2023.09.30 |
[C#] Collection<T>, CollectionBase, ReadOnlyCollection<T> (0) | 2023.09.28 |
[C#] SortedDictionary<TKey,TValue>, SortedList<Tkey,TValue>, SortedList (0) | 2023.09.26 |
[C#] OrderedDictionary, ListDictionary, HybridDictionary (0) | 2023.09.24 |