내 원하는 Food
것이 다른 인스턴스와 동일한 때마다 클래스를 테스트 할 수 있도록 Food
. 나중에 List에 대해 사용하고 그 List.Contains()
방법 을 사용하고 싶습니다 . 구현 IEquatable<Food>
또는 재정의 해야합니까 Object.Equals()
? MSDN에서 :
이 메소드는 오브젝트의 IEquatable.Equals 메소드 (목록의 값 유형)에 대한 정의에 정의 된대로 기본 동등 비교기를 사용하여 동등성을 판별합니다.
그래서 다음 질문은 .NET 프레임 워크의 어떤 함수 / 클래스를 사용 Object.Equals()
합니까? 처음에 사용해야합니까?
답변
주된 이유는 성능입니다. 제네릭은 .NET 2.0에 도입되었을 때 그들은 같은 깔끔한 클래스의 무리를 추가 할 수 있었다 List<T>
, Dictionary<K,V>
, HashSet<T>
, 등이 구조를 많이 사용 GetHashCode
하고 Equals
. 그러나 가치 유형의 경우 권투가 필요했습니다. IEquatable<T>
구조체가 강력한 형식의 Equals
메서드를 구현할 수 있으므로 권투가 필요하지 않습니다. 따라서 일반 컬렉션에 값 유형을 사용할 때 훨씬 더 나은 성능을 제공합니다.
참조 유형은 그다지 도움이되지 않지만 IEquatable<T>
구현을 통해 System.Object
자주 호출되는 경우 차이를 만들 수 있는 캐스트를 피할 수 있습니다.
Jared Parson의 블로그 에서 언급했듯이 여전히 Object 재정의를 구현해야합니다.
답변
MSDN 에 따르면 :
당신이 구현하는 경우
IEquatable<T>
, 당신은 또한의 기본 클래스 구현을 오버라이드 (override)
Object.Equals(Object)
하고GetHashCode
그래서 그들의 행동은 그와 일치하는지IEquatable<T>.Equals
방법. 당신은 대체를 할 경우
Object.Equals(Object)
, 재정의 된 구현은 정적에 대한 호출에서 호출되는Equals(System.Object,
클래스에 방법. 이렇게하면
System.Object)Equals
메소드 의 모든 호출이 일관된 결과를 리턴합니다.
따라서 클래스가 어떻게 사용되는지에 따라 호출 될 수 있다는 점을 제외하고는 둘 사이에 실질적인 기능적 차이가없는 것 같습니다. 성능 관점에서 볼 때 권투 / 언 박싱 페널티가 없기 때문에 일반 버전을 사용하는 것이 좋습니다.
논리적 관점에서 인터페이스를 구현하는 것이 좋습니다. 객체를 재정의한다고해서 클래스가 실제로 동일하다는 사실을 다른 사람에게 알리지는 않습니다. 재정의는 클래스를 수행하지 않거나 얕은 구현 일 수 있습니다. “이것은 평등 검사에 유효합니다!” 더 나은 디자인입니다.
답변
Josh가 말한 내용을 실제 사례로 확장합니다. 조쉬에게 +1-내 대답에 똑같이 쓰려고했다.
public abstract class EntityBase : IEquatable<EntityBase>
{
public EntityBase() { }
#region IEquatable<EntityBase> Members
public bool Equals(EntityBase other)
{
//Generic implementation of equality using reflection on derived class instance.
return true;
}
public override bool Equals(object obj)
{
return this.Equals(obj as EntityBase);
}
#endregion
}
public class Author : EntityBase
{
public Author() { }
}
public class Book : EntityBase
{
public Book() { }
}
이렇게하면 모든 파생 클래스에서 즉시 사용할 수있는 재사용 가능한 Equals () 메서드가 있습니다.
답변
를 호출하면 object.Equals
값 유형에 대한 비싼 권투가 발생합니다. 성능에 민감한 시나리오에서는 바람직하지 않습니다. 해결책은 IEquatable<T>
입니다.
public interface IEquatable<T>
{
bool Equals (T other);
}
배후의 아이디어 IEquatable<T>
는 결과는 object.Equals
같지만 더 빠르다는 것입니다. 구속 조건 where T : IEquatable<T>
은 다음과 같은 일반 유형과 함께 사용해야합니다.
public class Test<T> where T : IEquatable<T>
{
public bool IsEqual (T a, T b)
{
return a.Equals (b); // No boxing with generic T
}
}
그렇지 않으면에 바인딩됩니다 slower object.Equals()
.