var a = ImmutableList<int>.Empty.Add(1).Add(2).Add(3);
var b = ImmutableList<int>.Empty.Add(1).Add(2).Add(3);
Console.WriteLine(a.Equals(b)); // False
In the code above the a.Equals(b)
calls Object.Equals
, because ImmutableList<T>
doens't override Equals(object)
, and as ImmutableList<T>
is a reference type Object.Equals
does (the useless) reference comparison.
Question: Why doesn't ImmutableList<T>
override .Equals
? It would be straightforward and expected to have it compare each contained object with .Equals
and return the result based on those comparisons. It would even be consistent to test rest of the framework (see class String
)
note: the above code is tested with System.Collections.Immutable.1.1.38-beta-23516
You want to do is test the contents of the collections for equality. No .NET collections override Equals
to do this. Instead, use SequenceEqual
:
Console.WriteLine(a.SequenceEqual(b));
As to why -- that's a matter of opinion, I suppose. Most reference oriented platforms do their best to not confuse reference equality with content equality.
String
is actually very special case and though it does implement IEnumerable
, isn't typically treated as a proper container in the sense that List
/etc. are.
You 'could' create a wrapper class and override the Equality and HashCode methods... This could be helpful for c# records so that you don't have to keep overriding the auto generated methods.
public sealed class ImmutableListSequence<T>
{
public ImmutableListSequence(ImmutableList<T> items)
{
Items = items;
}
public ImmutableList<T> Items { get; }
public override int GetHashCode()
{
unchecked
{
return Items.Aggregate(0, (agg, curr) => (agg * 397) ^ (curr != null ? curr.GetHashCode() : 0));
}
}
public override bool Equals(object? obj)
{
if (obj is ImmutableListSequence<T> second)
{
return Items.SequenceEqual(second.Items);
}
return false;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With