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은 순서에 구애받지 않으므로 목록이 다르게 정렬되는지는 중요하지 않습니다. 그것들은 동등한 멤버만을 포함하고 있다는 것만 중요합니다.
참고 : 이상한 이름은 메서드가 목록의 요소 순서를 고려하지 않는다는 것을 의미합니다. 목록의 요소 순서를 신경 쓰면이 방법이 적합하지 않습니다!