0

I get that one instance of a class is not equal to another instance of the same class, even if both instances contain the properties & fields of the instances contain the same values. For example, in the below code, even though both instances of TestClass have the same value for the TestValue01 and TestValue02 properties, the comparison will equate to false and "Boooo!" will be printed.

static void Main(string[] args)
{
    TestClass testClassInstance01 = new TestClass(1, 1);
    TestClass testClassInstance02 = new TestClass(1, 1);

    if (testClassInstance01 == testClassInstance02)
    {
        Console.WriteLine("Woohoo!");
    }
    else
    {
        Console.WriteLine("Boooo!");
    }
}

class TestClass
{
    public int TestValue01 { get; private set; }
    public int TestValue02 { get; private set; }

    public TestClass(int testValue01, int testValue02)
    {
        TestValue01 = testValue01;
        TestValue02 = testValue02;
    }
}

Is it at all possible to force this kind of comparison to equate to true?

The obvious thing to do is to compaire the property values, like below, but I'm curious if this can be avoided.

if (testClassInstance01.TestValue01 == testClassInstance02.TestValue01
    && testClassInstance01.TestValue02 == testClassInstance02.TestValue02)
{
    Console.WriteLine("Woohoo!");
}
else
{
    Console.WriteLine("Boooo!");
}

EDIT

For completeness, what I was looking for was operator overloading. Here is the code I require for this example to return true:

class TestClass
{
    public int TestValue01 { get; private set; }
    public int TestValue02 { get; private set; }

    public TestClass(int testValue01, int testValue02)
    {
        TestValue01 = testValue01;
        TestValue02 = testValue02;
    }

    public static bool operator==(TestClass tc01, TestClass tc02)
    {
        return tc01.TestValue01 == tc02.TestValue01 && tc01.TestValue02 == tc02.TestValue02;
    }

    public static bool operator!=(TestClass tc01, TestClass tc02)
    {
        return tc01.TestValue01 != tc02.TestValue01 || tc01.TestValue02 != tc02.TestValue02;
    }
}
devklick
  • 2,000
  • 3
  • 30
  • 47
  • 3
    Possible duplicate of [Operator overloading ==, !=, Equals](https://stackoverflow.com/questions/25461585/operator-overloading-equals) – Mong Zhu Dec 16 '18 at 20:59
  • @MongZhu your right, this is exactly what I was after. I'm currently unable to mark this question as a duplicate though. Not sure why (pending edit, perhaps?)... – devklick Dec 16 '18 at 21:18
  • Possible duplicate of [How to quickly check if two data transfer objects have equal properties in C#?](https://stackoverflow.com/questions/986572/how-to-quickly-check-if-two-data-transfer-objects-have-equal-properties-in-c) – mjwills Dec 16 '18 at 22:21

2 Answers2

2

Marij Khans answer is basically correct. Without overloading the operator(s) ReferenceEquals(object, object) is used for '==' and '!=' when applied to class instances and, because in your example you compare two instances, the result is 'false'. The full blown solution looks like this:

public class TestClass : IEquatable<TestClass>
{
    public int TestValue01 { get; private set; }
    public int TestValue02 { get; private set; }

    public TestClass(int testValue01, int testValue02)
    {
        TestValue01 = testValue01;
        TestValue02 = testValue02;
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as TestClass);
    }

    public bool Equals(TestClass other)
    {
        return other != null &&
            TestValue01 == other.TestValue01 &&
            TestValue02 == other.TestValue02;
    }

    public static bool operator ==(TestClass test1, TestClass test2)
    {
        return EqualityComparer<TestClass>.Default.Equals(test1, test2);
    }

    public static bool operator !=(TestClass test1, TestClass test2)
    {
        return !(test1 == test2);
    }
}

Besides the overloading of the operators '==' and '!=' the implementation of the IEquatable interface ensures that comparisons always work as expected, even when used as key in a dictionary or the pattern a.Equals(b) is used. For better speed when searching large collections with instances of this class as key, you might even want to implement GetHashCode(), but that requires that the values used when generating the hash code have to be readonly (i.e. removing the setter of the properties, so they can only be set from within the constructor).

Axel.S
  • 66
  • 2
1

Overload the == operator. I haven’t done c# in a while so I’m a little rusty but you can take a look at operator overloading to define this type of behaviour

Marij Khan
  • 151
  • 1
  • 12
  • Thats exactly what I was after, thanks! Someone has commented a similar link, which gave me an example to follow. – devklick Dec 16 '18 at 21:06