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;
}
}
}
2つのリストが異なるかどうかを知るだけでよく、それらの違いを知る必要がない場合もあります。その場合は、この拡張メソッドをプロジェクトに追加することを検討してください。リストされたオブジェクトは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
しなければならない論理的に互換性のある方法で、インスタンスのプロパティを操作します。
同じ内容の2つのリストはまだ異なるオブジェクトであり、異なるハッシュコードを生成します。これら2つのリストを同等に扱う必要があるGetHashCode
ため、それぞれに同じ値を生成させる必要があります。これは、ハッシュコードをリスト内のすべての要素に委任し、標準のビットごとのXORを使用してそれらすべてを結合することで実現できます。XORは順序にとらわれないため、リストのソート順が異なっていてもかまいません。同等のメンバーのみが含まれていることが重要です。
注:奇妙な名前は、メソッドがリスト内の要素の順序を考慮しないことを意味します。リスト内の要素の順序を気にする場合は、この方法は適していません。