CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6
  1. #1
    Join Date
    Nov 2006
    Posts
    357

    Crazy overidding Equals behaviour

    Hey,

    Im going a bit nuts, ive got a class which using the resharper built in equality creator has 2 equals methods...

    Code:
    public override bool Equals(object obj)
            {
                return base.Equals(obj);
            }
    
            public bool Equals(ThisClass other)
            {
                if (ReferenceEquals(null, other)) return false;
                if (ReferenceEquals(this, other)) return true;
                return other.Id == Id;
            }
    Now for some reason when im doing a unit test and I create a new ThisClass and do an equals() check against it with another ThisClass it always hits the default Equals(object) method, and not the more specific Equals(ThisClass)...

    Im banging my head against a wall at the moment a bit confused as to why this is...

    I've stepped through and the class is definatly of the right type, even in the Equals(object) method i can see that it is of type ThisClass.

    Anyone had anything similar before?

  2. #2
    Join Date
    May 2007
    Posts
    1,546

    Re: Crazy overidding Equals behaviour

    Code:
            public override bool Equals(object obj)
            {
                return Equals(obj as ThisClass);
            }
    
            public bool Equals(ThisClass other)
            {
                if (ReferenceEquals(null, other)) return false;
                if (ReferenceEquals(this, other)) return true;
                return other.Id == Id;
            }
    That'll fix it.

    The 'public bool Equals (ThisClass)' method will only be invoked if you do something like:
    new ThisClass ().Equals (otherThisClass);

    If you do:
    object o = new ThisClass ();
    o.Equals (otherThisClass); you will not invoke the 'Equals (ThisClass)' method as it's not a virtual method so for all intents and purposes it does not exist when your class is considered to be of type 'object'.

    What you're hitting here is the difference between virtual and non virtual methods. You'd have to look up a tutorial on the interwebs to get a better explanation of exactly what goes on. It's simple when you know it, but can be hard to explain without diagrams
    www.monotorrent.com For all your .NET bittorrent needs

    NOTE: My code snippets are just snippets. They demonstrate an idea which can be adapted by you to solve your problem. They are not 100% complete and fully functional solutions equipped with error handling.

  3. #3
    Join Date
    Nov 2006
    Posts
    357

    Re: Crazy overidding Equals behaviour

    Hey mutant,

    If that were the case then I wouldnt be in this position, im calling equals on an instance of the class... so an example would be:

    Code:
    var myClass1 = new ThisClass();
    var myClass2 = new ThisClass();
    
    var result = myClass1.Equals(myClass2);
    I must have made a stupid mistake i cannot see somewhere as unless the compiler is inferring an instance of ThisClass as an object this shouldnt happen...

    Thanks for your help will investigate further...

  4. #4
    Join Date
    Nov 2006
    Posts
    357

    Re: Crazy overidding Equals behaviour

    Just incase this is one of those important facts i have overlooked, it also includes generics...

    So it would be more accurate to say the test code looks something like:

    Code:
    protected void TestSerializedData<T>(T originalObject, string serializedData)
    {
        // an extension method that attempts to unserialize a string to an object
        // returns an object of type T or throws an exception
        var unserializedObject = serializedData.Unserialize<T>();
        Assert.IsTrue(originalObject.Equals(unserializedObject));
    }
    I have a lot of serialization sanity tests that check over alot of entities, so i have an inner test that does the generic testing part for a given entity...

    As i said originally debugging shows that the original and unserialized object are both of type T (ThisClass in the example), so im baffled as to why its acting this way... if one WAS infact type object i would fully understand...

  5. #5
    Join Date
    May 2007
    Posts
    1,546

    Re: Crazy overidding Equals behaviour

    I'd have to go read the ECMA spec for C# to be sure, but i bet at compile time the only method guaranteed to fultill the contract is object.Equals (object) which is why it's being invoked in this case. If you use reflector you should be able to see the IL generated for this and I bet it's a callvirt to the object.Equals method.

    In a non-generic case you'd call the method you expect. This is why you have to be sure to override equals properly if you want every call to .Equals to have the same effect.
    www.monotorrent.com For all your .NET bittorrent needs

    NOTE: My code snippets are just snippets. They demonstrate an idea which can be adapted by you to solve your problem. They are not 100% complete and fully functional solutions equipped with error handling.

  6. #6
    Join Date
    Nov 2006
    Posts
    357

    Re: Crazy overidding Equals behaviour

    Will do, thanks for the advice!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured