using System.Collections.Generic;
using System.Linq;
namespace YourProject.Extensions
{
public static class ListExtensions
{
public static bool SetwiseEquivalentTo<T>(this List<T> list, List<T> other)
where T: IEquatable<T>
{
if (list.Except(other).Any())
return false;
if (other.Except(list).Any())
return false;
return true;
}
}
}
때로는 두 목록이 다른지 여부 만 알고 그 차이점이 무엇인지 알아야 합니다 . 이 경우이 확장 방법을 프로젝트에 추가하십시오. 나열된 객체는 IEquatable을 구현해야합니다!
용법:
public sealed class Car : IEquatable<Car>
{
public Price Price { get; }
public List<Component> Components { get; }
...
public override bool Equals(object obj)
=> obj is Car other && Equals(other);
public bool Equals(Car other)
=> Price == other.Price
&& Components.SetwiseEquivalentTo(other.Components);
public override int GetHashCode()
=> Components.Aggregate(
Price.GetHashCode(),
(code, next) => code ^ next.GetHashCode()); // Bitwise XOR
}
Component
클래스가 무엇이든 여기에 표시된 메소드 Car
는 거의 동일하게 구현되어야합니다.
GetHashCode를 어떻게 작성했는지 주목하는 것이 매우 중요합니다. 순서가 제대로 구현하기에 IEquatable
, Equals
그리고 GetHashCode
해야한다 논리적으로 호환 방식으로 인스턴스의 속성에서 작동합니다.
내용이 같은 두 목록은 여전히 다른 객체이며 다른 해시 코드를 생성합니다. 이 두 목록이 동일하게 취급되기를 원하므로 각 목록에 GetHashCode
대해 동일한 값을 생성 해야 합니다. 해시 코드를 목록의 모든 요소에 위임하고 표준 비트 XOR을 사용하여 해시 코드를 모두 결합하여이를 수행 할 수 있습니다. XOR은 순서에 구애받지 않으므로 목록이 다르게 정렬되는지는 중요하지 않습니다. 그것들은 동등한 멤버만을 포함하고 있다는 것만 중요합니다.
참고 : 이상한 이름은 메서드가 목록의 요소 순서를 고려하지 않는다는 것을 의미합니다. 목록의 요소 순서를 신경 쓰면이 방법이 적합하지 않습니다!