それでは、各リストに移動して、少なくとも 1 つの他のリストに含まれていないアイテムと、少なくとも 1 つの他のリストに含まれていないすべてのアイテムを特定します。
これを行うには、すべてのリストですべての項目を見つけることから始めます。それが各リストの「交差点」です。
一度取得すると、Exceptすべての作業が完了します。特定のリストのすべてのアイテムexceptは、交差点にあるがその特定のリストにないアイテムを提供します。交差点リストのアイテムは、交差点Exceptにないすべてのアイテムです。
public static IEnumerable<SetDifference<T>> ComputeDifferences<T>(IList<List<T>> lists)
{
    if (lists.Count == 0)
        yield break;
    var intersection = new HashSet<T>(lists.First());
    foreach (var list in lists.Skip(1))
    {
        intersection.IntersectWith(list);
    }
    var output = new List<SetDifference<T>>();
    foreach (var list in lists)
    {
        yield return new SetDifference<T>(
            list: list,
            additionalObjects: list.Except(intersection),
            missingObjects: intersection.Except(list));
    }
}
出力を提供するために使用される単純なデータホルダーを次に示します。
public class SetDifference<T>
{
    public SetDifference(List<T> list, IEnumerable<T> additionalObjects,
            IEnumerable<T> missingObjects)
    {
        List = list;
        AdditionalObjects = additionalObjects;
        MissingObjects = missingObjects;
    }
    public List<T> List { get; private set; }
    public IEnumerable<T> AdditionalObjects { get; private set; }
    public IEnumerable<T> MissingObjects { get; private set; }
}
を使用しているため、LINQ の他のセット操作と同様に、各項目HashSetのメソッドに依存するため、そのオブジェクトのメソッドを指定して適切な実装が必要であることに注意してください。GetHashCodeEquals