Consider the following code, where ClassOne
is a class derived from IClass
:
List<IClass> list = new List<IClass>();
list.Add(new ClassOne("foo", "bar"));
list.Add(new ClassOne("baz", "bam"));
List<IClass> list2 = new List<IClass>();
list2.Add(new ClassOne("foo", "bar"));
list2.Add(new ClassOne("baz", "bam"));
if (list == list2)
Console.WriteLine("Lists are equal.");
else
Console.WriteLine("Lists are NOT equal.");
The equality operator returns false (i.e. lists do not match), besides the fact the the operator ==
, operator !=
, Equals(ClassOne)
, Equals(object)
and GetHashCode()
have been implemented/overridden for ClassOne
. Why is that? I would expect the equality operator to return true. Are there any other methods/interfaces that must be implemented for the ==
operator to work as expected?
For reference, here's the implementation of ClassOne
and IClass
:
public interface IClass
{
string getA();
string getB();
} //interface
public class ClassOne : IClass, IEquatable<ClassOne>
{
public ClassOne(string a, string b)
{
strA = a;
strB = b;
}
public string getA()
{
return strA;
}
public string getB()
{
return strB;
}
public bool Equals(ClassOne other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
if (!string.Equals(strA, other.strA))
return false;
return string.Equals(strB, other.strB);
}
public override bool Equals(object other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
if (other is ClassOne)
{
ClassOne c1 = (ClassOne)other;
return Equals(c1);
}
//not ClassOne, so it is not equal
return false;
}
public override int GetHashCode()
{
int hc_a = -1;
if (null != strA)
hc_a = strA.GetHashCode();
int hc_b = -1;
if (null != strB)
hc_b = strB.GetHashCode();
return hc_a ^ hc_b;
}
public static bool operator ==(ClassOne left, ClassOne right)
{
if (ReferenceEquals(left, right)) return true;
if (ReferenceEquals(left, null) || ReferenceEquals(right, null))
return false;
return left.Equals(right);
}
public static bool operator !=(ClassOne left, ClassOne right)
{
return !(left == right);
}
private string strA, strB;
} //class
Any help or hints in the right direction will be appreciated. Thanks.
Why is that? I would expect the equality operator to return true.
Not correct - the ==
operator (and Equals()
) are not defined on List<T>
to check the equality of its contents - it defaults to reference equality from the operator defined on object
. Since the two lists are different objects, ==
returns false.
You can use the Linq SequenceEqual
method to determine if two lists contain equal objects in the same order:
if (list.SequenceEqual(list2))
Console.WriteLine("Lists are equal.");
else
Console.WriteLine("Lists are NOT equal.");