Reputation: 43
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?
Upvotes: 4
Views: 265
Reputation: 55720
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:
public class StringEnumerable : IEnumerable, IEnumerable<String>
{
IEnumerator<String> IEnumerable<String>.GetEnumerator()
{
yield return "TEST";
}
public IEnumerator GetEnumerator()
{
// without the explicit cast of `this` to the generic interface the
// method would call itself infinitely until a StackOverflowException occurs
return ((IEnumerable<String>)this).GetEnumerator();
}
}
If you remove the explicit cast from non-generic interface implementation it will cause an infinite loop.
Upvotes: 2
Reputation: 89661
The cast is redundant.
Perhaps it may have been necessary before the code was refactored from something else.
Typically you see a lot of fluff left in code over long system life-cycles where designs have changed.
You may also see other redundant constructs when language features have changed (i.e. C# automatic properties) over time.
I think redundant code decreases readability and tools like Resharper will warn you and help you remove them.
Upvotes: 2
Reputation: 1377
I don't know about "all" examples but indeed the 2 variants of code should work identically. Maybe they just think that explicit casting is more readable.
Upvotes: 1
Reputation: 560
If your question is simply why the examples cast the PeopleNameComparer to IComparer, you are correct that it is not necessary at all. I would imagine it is for clarity to demonstrate to beginners that there is the implied relationship between the result and the interface.
Upvotes: 1