equalityCompaver .default 오해?
-
11-12-2019 - |
문제
Class Person
가 있으며 IEquatable<Person>
에서 equals () 메서드를 구현합니다 (Object.Equals
메소드를 무시하고 GetHashCode () 메소드를 지금 무시할 수 있음)
class Person : IEquatable<Person>
{
public string Name { get; set; }
public bool Equals(Person other)
{
return this.Name == other.Name;
}
public override bool Equals(object obj)
{
var person = obj as Person;
return person != null && person.Name == Name;
}
}
.
확인, 시작 :
Person p1 = new Person() { Name = "a" };
Person p2 = new Person() { Name = "a" };
List<Person> lst1 = new List<Person>() { p1 };
List<Person> lst2 = new List<Person>() { p2 };
.
이 줄에 대해 이야기 할 수 있습니다.
bool b = lst1.SequenceEqual(lst2, EqualityComparer<Person>.Default);
.
이 부분을 이해하는 데 문제가 있습니다.
EqualityComparer<Person>.Default
.
클래스가 EqualityComparer<Person>.Default
를 구현하는지 확인하는 IEquatable
가 Equals(Person other)
가 아니라 Equals(object obj)
메소드를 확인합니다. 권투 를 피하는 것이 유리합니다.
그러나
Equals(Person other)
는 EqualityComparer<Person>.Default
와 함께 을 실행합니다.
(IEquatable 구현이 있기 때문에)
그래서 우리는 어떤 권투에 대해 이야기하고 있습니까? 거기에 없어!
Equals(object obj)
가 실행되는 유일한 시간은 다음과 같습니다 :
.
bool b = lst1.SequenceEqual(lst2,EqualityComparer<Object>.Default);
그러나 나는 프로그래머입니다! 실제로 object
가 실제로 Person
를 보내지 않을 것입니다!
누락 된 것입니까? EqualityComparer<Object>.Default
의 이익을 이해하는 데 어려움이 있습니다. 누군가 내가 틀린 것을 증명하는 예를 들어 내게 줘?
해결책
If you pass in null
as the second parameter or if you don't pass in a second argument at all (which is basically the same), the implementation of SequenceEquals will call EqualityComparer<T>.Default
itself (decompile Enumerable
to see this). That explains why you don't see a difference whether you provide EqualityComparer<T>.Default
or not.
So in the end the second parameter only makes sense if you want to use an equality comparer other than EqualityComparer<T>.Default
.
다른 팁
That you can pass in IEqualityComparer<object>.Default
is an effect of generic contravariance, added in .NET 4.
Essentially, an IEqualityComparer<BaseType>
can be used whenever an IEqualityComparer<DerivedType>
is required, where DerivedType : BaseType
. Since Person
derives from Object
, this means that an IEqualityComparer<Object>
can be used wherever an IEqualityComparer<Person>
is required.
The answer is here: http://msdn.microsoft.com/en-us/library/ms131187(v=vs.110).aspx
For a value type, you should always implement IEquatable and override Object.Equals(Object) for better performance. Object.Equals boxes value types and relies on reflection to compare two values for equality. Both your implementation of Equals and your override of Object.Equals should return consistent results.
If you do not override Equals and GetHashCode, EqualityComparer.Default actually takes care of that for you.