I understand how to use the IComparer interface with helper classes which provide custom ways to sort. For example, here is a typical example which is very much like all the examples I have seen on the web including Microsoft’s online help page:
// This helper class is used to sort an array of people by name,
// where 'Person' is a class type.
public class PeopleNameComparer : IComparer
{
// Test the name of each object.
int IComparer.Compare(object o1, object o2)
{
Person p1 = o1 as Person;
Person p2 = o2 as Person;
if (p1 != null && p2 != null)
return string.Compare(p1.Name, p2.Name);
else
throw new ArgumentException("Parameter is not a Person!");
}
}
I also understand that if we have an array of type Person (myPeople), we can then sort this array with:
Array.Sort(myPeople, new PeopleNameComparer());
In this case we are creating a new PeopleNameComparer object which is of type IComparer and passing it into the Array.Sort() method as a second parameter.
Now to make things neater, we can implement a property to provide the object user with a more friendly way to invoke the custom sort:
public static IComparer SortByName
{ get { return (IComparer)new PeopleNameComparer(); } }
What I don’t understand with this kind of Property is why do all the examples use the (IComparer) cast to cast the newly created helper class(PeopleNameComparer in this example) into an IComparer object when this object is already of type IComparer? I have tried without the cast and the code appears to work fine:
// This property seems to work fine without the cast?
public static IComparer SortByName
{ get { return new PeopleNameComparer(); } }
I could understand it if the ‘new’ keyword returned a plain vanilla System.Object type which would then have to be casted to the appropriate IComparer, but just cannot see the need for the cast here.
But I followed Microsoft’s example, and my example is similar to an example in my Pro C# book.
Is there any reason why a cast would be necessary here?
Using an explicit cast is more explicit. Pardon the truism.. but it’s just that. It helps make the code more readable.
In some cases explicit casts can help the runtime disambiguate a cast if there are multiple possible options but that doesn’t seem to occur with return type. Only in expressions. Following is a common example where you would need an explicit cast in an expression:
If you remove the explicit cast from non-generic interface implementation it will cause an infinite loop.