views:

384

answers:

3

I've read in several articles that

for reference types using IEquatable reduces the use of casting

Can someone kindly provide a convincing example.

Thanks

Clarry

A: 

I believe your answer is here, http://msdn.microsoft.com/en-us/library/ms131190.aspx. Read the remarks section on the page.

nickyt
+1  A: 

Do you know this article? It says

If you want to have your own implementation, you can override this method. Since the Equals method has a parameter of type Object, a cast will be needed in order to be able to access class specific members.

This is where the IEquatable interface comes in. The IEquatable is a new generic interface in .NET 2.0 that allows you to do the same as the System.Object.Equals method but without having to perform casts. So, when implementing this interface, you can reduce the number of casts, which is a good thing for performance. Especially when working a lot with generic collections, since generic collections make use of this equality comparison in some of their methods (List.Equals(), List.IndexOf(), List.LastIndexOf(), ...).

Due to its generic type parameter, IEquatable<T> can provide type-checking at compiletime so you don't have to cast and late-bind with objects.

Dario
@Dario: Isn't C# early bound, unless you use dynamic?
+2  A: 

Just to add a simple example after Dario's explanation:

class Person : IEquatable<Person>
{
    public string Name { get; set; }

    public override bool Equals(object obj)
    {
        if (obj is Person)
        {
            Person other = (Person)obj;
            // check equality
        }
        return base.Equals(obj);
    }

    #region IEquatable<Person> Members

    public bool Equals(Person other)
    {
        // check equality without cast
    }

    #endregion
}

Note: This is just a little fragment that shows why this avoids a cast. For a correct implementation check the docs:

If you implement IEquatable<(Of <(T>)>), you should also override the base class implementations of Object..::.Equals(Object) and GetHashCode so that their behavior is consistent with that of the IEquatable<(Of <(T>)>)..::.Equals method

bruno conde
You could just drop IEquatable<Person> from the class definition and the methods will still work the same way. So I don't see how IEquatable<Person> in itself reduces casting here. Help!
For example, if your implementing some kind of a collection that is expected to contain lots of items, performance is an important factor. In this case, you can request that all your items implement IEquatable<T> that offers slightly better performance. This way, important compare methods that can be called *trillions* of times can at lest avoid the cast in the Equals in each comparation.
bruno conde
@Bruno: I see! I had a quick peek at List<T>.Contains. This creates a Comparer which will use the implementation of IEquatable if the type implements it. Thanks, you've been an imense help!Nickyt's post also helped me get my head round this.Thanks guys!