implementing the Equals method with and w/o override

Hi,

I'm using .NET 2003 with .NET Framework 1.1.

I have a somewhat stupid question:

I created a new class (MyClass) that represent some value and implemented the Equals method the following way:

public bool Equals(Object obj)
{
// code here...
}

And if I try this code I get 'True' (since they hold the same value)

MyClass c1 = new MyClass(<<some value>>);
MyClass c2 =
new MyClass(<<same value as above>>);
Console.WriteLine(c1.Equals(c2));

BUT (!) if I insert c1 into an ArrayList and check:

int index = myArrayList.IndexOf(c2);

I get -1 on the index variable (c2 was not found).

Now, if I add override to the Equals implementation signature:

public override bool Equals(Object obj)
{
// code here...
}

c2 is found in the ArrayList.

So, I guess my question is what the override keyword exactly DO, and why did the Equals worked in my first example but not when using IndexOf (which uses Equals to determine its result)

Another small thing, the documentation says that IndexOf is using the CompareTo and Equals methods, well... which is it exactly

Thanks,
Roee.



Answer this question

implementing the Equals method with and w/o override

  • LiamD

    Hello. In general I understand the Equals() method.

    As I told my colleague to override the Equals() method, I got a result which was not expected by me:

    public static new bool Equals(object objA, object objB)
    {
    // perform some comparison
    }

    Now I wondered why there is a public static bool Equals() method anyway and what does the original implementation look like Unfortunately I could not find out by Reflector what the implementation by Microsoft does.

    I have never seen a line of code object.Equals(myObj1,myObj2); In which case is such a line more useful compared to myObj1.Equals(myObj2);

    Thanks, Thomas


  • bitbonk

    hi.,

    the static Equals() method can be used even your object reference is null.

    consider the following example:

    object obj1; // it is null
    object obj2; // it is also null

    // obj1.Equals(obj2) // it will throw expection ( NullReferenceException )

    Object.Equals ( obj1, obj2 ) // result is True.

    If you are not sure your object ( in my example, obj1 ) is null or not, just use the static method Object.Equals().

    I hope it'll help you,
    soemoe.

    P.S. please mark the correct one as your answer.



  • kalprin

    Yes, that is reasonnable for static objects.Equals().

    How can I mark your answer as correct Sorry, I'm new here and can't find a button or anything to do so. Perhaps that is because the post was not originally opened by me.

    Thanks, Thomas


  • Shrouber

    Hi,
    In .net, every Type (including class) is inherit -directly or indirectly- from System.Object. So your new class is inherit from System.Object.

    System.Object has this method.
    public virtual bool Equals(object obj);

    When you declare a new Equals method without using override keyword, the method is new method and which hide the base class method. (In your case, System.Object)

    The different between override and new method is here:

    public class A
    {
    public override bool Equals (object obj)
    {
    // class A's equal algorithm
    }
    }

    public class B
    {
    // if you omit new keyword, the complier will give a warning.
    public new bool Equals (object obj)
    {
    // class B's equal algorithm
    }
    }


    public class Test
    {
    public static void TestInherit()
    {
    // Class A
    A a1 = new A("some value");
    A a2 = new A("same as some value");

    bool b = a1.Equals(a2); // It will invoke class A's Equals method.

    Object o = (Object) a1; // cast to Object type.

    // It will also invoke class A's Equals method because of override keyword.
    b = o.Equals(a2);

    // Class B
    B b1 = new B("some vblue");
    B b2 = new B("same as some value");

    bool b = b1.Equals(b2); // It will invoke class B's Equals method.

    Object o2 = (Object) b1; // cast to Object type.

    // It will invoke System.Object's Equals method instead of class B's Equals method because class B's Eqauls method is a new method.( with or without new keyword.)
    b = o2.Equals(b2);
    }
    }


    In your case, the myArrayList.IndexOf() method which take the System.Object type as perameter. So, it convert to System.Object and call System.Object.Equals method instead of your Class's Equals method if it is not override method. The System.Object's Equals call static System.Object.ReferenceEquals method.


    public class ArrayList
    {
    ...
    ...
    ...

    public virtual int IndexOf(object value)
    {
    // here.. value is object type. it is implicitly converted.
    }
    }

    To solve your problem, just insert override keyword to your class Equals method.

    Cheers,
    Soe Moe

    P.S. please mark the correct one as Answer.



  • Brandon Bloom

    The answer of your questions in the difference between override and new what dose this mean

    as you know when member function declared in base class as virtual this let its child class to provide thier implementation of this method by overriding it

    so the override keyword say to the compiler  do not use my parent implementaion use mine instead i implement one myself the clear example of that if you  write drawing example you have parent class Shape that all other types of shape inherit from it



    class shape
    {
    public virtual Draw()
    {//base implementation}
    }
     
    class Rectangle:Shape
    {
    public override Draw()
    {//implement rectanfle drawing}
    }

     

    in the above example the rectangle class override base class Draw function

    now what if we write Rectangle class as the following



    class Rectangle
    {
    public void Draw()
    {//do it}
    }

     

    this not provide your implementation it actually create new method which its name like one in its parent class and hide it too

    ie Draw() in rectangle class have no relation with Draw()  in shape class

    and the compiler will give you warning about this

    so c# to let you provide function with the same name as its paren's method

    your write your class



    class Rectangle
    {
    public new virtual void Draw()
    {
    //do it
    }
    }

     

    now your seconed question why did the Equals worked in my first example but not when using IndexOf

    in your first example you called explicitlay your new method which called Equals

    but in ArrayList.IndexOf() want call your implementation of Equals by overriding it because you did not override the method the IndexOf was failed to compare your two objects you hide it by your method not override it

    your Third question Another small thing, the documentation says that IndexOf is using the CompareTo and Equals methods, well... which is it exactly

    this mean that IndexOf when  searching for item in arraylist it use CompareTo and Equals to compare item to another item

    some thing like



    public int IndexOF(object obj)
    {
    foreach(Object o in this.List)
    {
    if(o.Equals(obj))
    return 1;
    }
    return -1;


     



  • implementing the Equals method with and w/o override