To determine if 2 lists are equal, you would use either
SequenceEqual
or
Union
.
Let me show you why:
List<Item> itemsA = new();
List<Item> itemsB = new();
for (int i = 0; i < 10; i++)
{
itemsA.Add(new Item(i, $"item {i}"));
}
itemsB = itemsA.OrderBy(x => Guid.NewGuid()).ToList();
Console.WriteLine("SequenceEqual method");
var AreEqual = Enumerable.SequenceEqual(itemsA.OrderBy(e => e.Id), itemsB.OrderBy(e => e.Id));
Console.WriteLine($"Are Equal = {AreEqual}");
itemsB.Add(new(11, "imposter"));
AreEqual = Enumerable.SequenceEqual(itemsA.OrderBy(e => e.Id), itemsB.OrderBy(e => e.Id));
Console.WriteLine($"Are Equal = {AreEqual}");
Console.WriteLine();
Console.WriteLine("Intersect method");
itemsB = itemsA.OrderBy(x => Guid.NewGuid()).ToList();
int count = itemsA.Select(item => item.Id).Intersect(itemsB.Select(item => item.Id)).Count();
Console.WriteLine($"Are Equal = {count == itemsA.Count}");
itemsB.Add(new(11, "imposter"));
count = itemsA.Select(item => item.Id).Intersect(itemsB.Select(item => item.Id)).Count();
Console.WriteLine($"Are Equal = {count == itemsA.Count}");
Console.WriteLine();
Console.WriteLine("Union method");
itemsB = itemsA.OrderBy(x => Guid.NewGuid()).ToList();
count = itemsA.Select(item => item.Id).Union(itemsB.Select(item => item.Id)).Count();
Console.WriteLine($"Are Equal = {count == itemsA.Count}");
itemsB.Add(new(11, "imposter"));
count = itemsA.Select(item => item.Id).Union(itemsB.Select(item => item.Id)).Count();
Console.WriteLine($"Are Equal = {count == itemsA.Count}");
Console.WriteLine();
Console.WriteLine("Except method");
itemsB = itemsA.OrderBy(x => Guid.NewGuid()).ToList();
count = itemsA.Select(item => item.Id).Except(itemsB.Select(item => item.Id)).Count();
Console.WriteLine($"Are Equal = {count == 0}");
itemsB.Add(new(11, "imposter"));
count = itemsA.Select(item => item.Id).Except(itemsB.Select(item => item.Id)).Count();
Console.WriteLine($"Are Equal = {count == 0}");
record Item(int Id, string Name);
And the output:
SequenceEqual method
Are Equal = True
Are Equal = False
Intersect method
Are Equal = True
Are Equal = True
Union method
Are Equal = True
Are Equal = False
Except method
Are Equal = True
Are Equal = True
For
Intersect
and
Except
, you need an additional check:
itemsA.Count == itemsB.Count && count == itemsA.Count
UPDATE
As requested, the
SequenceEqual
as an extension method:
Console.WriteLine("extension method");
itemsB = itemsA.OrderBy(x => Guid.NewGuid()).ToList();
Console.WriteLine($"Are Equal = {itemsA.Eqaulity(itemsB)}");
itemsB.Add(new(11, "imposter"));
Console.WriteLine($"Are Equal = {itemsA.Eqaulity(itemsB)}");
public static class ItemCompareExtension
{
public static bool Eqaulity(this List<Item> itemsA, List<Item> itemsB)
=> Enumerable.SequenceEqual(itemsA.OrderBy(e => e.Id), itemsB.OrderBy(e => e.Id));
}
public record Item(int Id, string Name);
Output:
extension method
Are Equal = True
Are Equal = False
UPDATE #2
Comparing 2 different lists:
List<Item> itemsA = new();
List<Item> itemsB = new();
for (int i = 0; i < 10; i++)
{
itemsA.Add(new Item(i, $"item a {i}"));
}
for (int i = 0; i < 10; i++)
{
itemsB.Add(new Item(i, $"item b {i}"));
}
Console.WriteLine("extension method");
itemsB = itemsA.OrderBy(x => Guid.NewGuid()).ToList();
Console.WriteLine($"Are Equal = {itemsA.Eqaulity(itemsB)}");
itemsB.Add(new(11, "imposter"));
Console.WriteLine($"Are Equal = {itemsA.Eqaulity(itemsB)}");
Output:
extension method
Are Equal = True
Are Equal = False