JMB
JMB

Reputation: 66

C# - Using equals operators and methods between child and parent classes pointing to the same memory location

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.)

Upvotes: 1

Views: 1551

Answers (2)

Jonathon Chase
Jonathon Chase

Reputation: 9704

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.

Upvotes: 0

Peter Duniho
Peter Duniho

Reputation: 70701

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;
    }
}

Upvotes: 3

Related Questions