Icemanind
Icemanind

Reputation: 48736

Overriding == does't seem to work in inherited class

I'm working on a program that's part of a much larger program, but I created this simple application to demonstrate the issue I'm running into. Here is my code:

using System;


namespace ConsoleApplication5
{
    class Program
    {
        static void Main(string[] args)
        {
            var bear = new Animal("Bear");
            var bear2 = new Animal("Bear");
            var dog = new Dog("Woof!", "Dog");
            var dog2 = new Dog("Bow-Wow!", "Dog");

            AreEqual(bear, bear2);
            AreEqual(dog2, dog);
        }

        private static void AreEqual(Animal animal1, Animal animal2)
        {
            if (animal1 == animal2)
                Console.WriteLine($"{animal1,15} == {animal2}");
            else
                Console.WriteLine($"{animal1,15} != {animal2}");
        }
    }

    public sealed class Dog : Animal
    {
        public string Action { get; }

        public static bool operator ==(Dog x, Dog y)
        {
            return x.Name == y.Name && x.Action == y.Action;
        }

        public static bool operator !=(Dog x, Dog y)
        {
            return !(x.Name == y.Name && x.Action == y.Action);
        }

        public override bool Equals(object obj)
        {
            if (!base.Equals(obj))
            {
                return false;
            }
            Dog rhs = (Dog)obj;
            return Action == rhs.Action;
        }

        public override int GetHashCode()
        {
            return base.GetHashCode() ^ Action.GetHashCode();
        }

        public Dog(string action, string animalName) : base(animalName)
        {
            Action = action;
        }

        public override string ToString()
        {
            return $"{Name} ({Action})";
        }
    }

    public class Animal
    {
        public string Name { get; }

        public Animal(string animalName)
        {
            Name = animalName;
        }

        public static bool operator ==(Animal x, Animal y)
        {
            return x.Name == y.Name;
        }

        public static bool operator !=(Animal x, Animal y)
        {
            return x.Name != y.Name;
        }

        public override bool Equals(object obj)
        {
            if (obj == null)
                return false;
            if (ReferenceEquals(obj, this))
                return true;
            if (obj.GetType() != GetType())
                return false;

            Animal rhs = obj as Animal;

            return Name == rhs.Name;
        }

        public override int GetHashCode()
        {
            return Name.GetHashCode();
        }

        public override string ToString()
        {
            return Name;
        }
    }
}

When I run the program, I am seeing this on the screen:

          Bear == Bear
Dog (Bow-wow!) == Dog (Woof!)

This is not correct. What I am expecting to see is this:

          Bear == Bear
Dog (Bow-wow!) != Dog (Woof!)

In the Dog class, I overrode the == operator which compares the Name fields and Action fields. Clearly the Action fields are different for each instance, so I'm not understanding why it's saying they are equal. Any help would be appreciated. I'm sure this is something simple I'm overlooking.

Upvotes: 1

Views: 64

Answers (3)

JohanP
JohanP

Reputation: 5472

Change

if (animal1 == animal2)

to

if (animal1.Equals(animal2))

Upvotes: 0

Steve
Steve

Reputation: 11973

The operators you are overloading are static, static to the class that it belongs to.

It has a similar concept as the new keyword instead of override keyword that you are hoping for.

you can read more about new vs override here

basically the method gets executed is based on the type you cast it to. You are casting both objects to Animal inside

private static void AreEqual(Animal animal1, Animal animal2)

so the == operator for Animal gets executed.

if you just do

Console.WriteLine(dog == dog2);

it will return false.

Upvotes: 1

Tim
Tim

Reputation: 6060

You are getting the == operator of Animal because AreEqual() is operating on Animals. This operator is not a virtual method that is inherited. You should use Equals() instead if you want inheritance

Upvotes: 3

Related Questions