1

So, I have searched all over stackoverflow and can't seem to find just the right answer to my question.

My question is, will equality comparison between a child object and a parent object ever return false when they point to the same memory location, and if so why? Meaning, am I soley comparing a single pointer? Or is there more going on in the background? This is related to the question "How does the compiler "see" the type of the object, and differentiate between the parent and the child (while still equating their pointers)?"

I was trying to understand this by looking at the references here and here.

Code example,

ChildType childTypeObject = new ChildType();

ParentType parentTypeObject = childTypeObject as ParentType;

if (parentTypeObject == childTypeObject)
{
    // Will this always get executed?
}

EDIT:

(This is assuming the child class has not overloaded the == operator. So, if you like, use the ReferenceEquals() comparison instead.)

JMB
  • 66
  • 10

2 Answers2

3

Will equality comparison between a child object and a parent object ever return false when they point to the same memory location, and if so why?

Sure, see below.

The == operator can be overloaded, but the compiler can only call the implementation it knows about. If only the base type overload can be applied (i.e. at least one of the operands is only the base type), then the base type implementation is called, and this implementation can easily be different from the derived type implementation.

This is why overloading the == operator (and related) should be done rarely and carefully. It takes some effort to ensure that the semantics of the operator are consistent, predictable, and match one's intuitive understanding of relationships between the objects.

class Program
{
    static void Main(string[] args)
    {
        Derived d = new Derived();
        Base b = d;

        Console.WriteLine($"b == d: {b == d}");
    }
}

class Base
{
    public static bool operator ==(Base b1, Base b2)
    {
        return false;
    }

    public static bool operator !=(Base b1, Base b2)
    {
        return true;
    }
}

class Derived : Base
{
    public static bool operator ==(Derived b1, Derived b2)
    {
        return true;
    }

    public static bool operator !=(Derived b1, Derived b2)
    {
        return false;
    }
}
Peter Duniho
  • 68,759
  • 7
  • 102
  • 136
  • Thanks @Peter Duniho, but I should have put in my question "assuming they share the same implementation of the == operator." See edited above. – JMB Feb 08 '18 at 00:23
  • _"I should have put in my question "assuming they share the same implementation of the == operator." "_ -- that makes no sense. The "same implementation" will obviously return the same result. If it didn't, it's obviously not the same implementation. – Peter Duniho Feb 08 '18 at 00:25
0

If the cast succeeds, the second variable is still the same reference as the first's and they share referential equality. It's really even the original type before the cast as far as the runtime is concerned.

void Main()
{
    B b = new B();
    A a = b as A;
    Console.WriteLine(a.GetType().Name); // Output B
}

public class A {}
public class B : A {}

Unless you change the implementation of an operator like Peter did in his answer (or possibly through some other form of hackery) then referential equality should hold.

Jonathon Chase
  • 9,396
  • 21
  • 39