views:

73

answers:

9

I'm implementing an

int IComparer.Compare(object x, object y);

from the IComparer interface. I know the objects are of type Class1, and I know one of its members is class1Instance.myDate, of type DateTime.

What I want to do is something along the lines of:

DateTime.Compare( (Class1)x.myDate, (Class1)y.myDate);

But casting this way doesn't work. Is there any alternative to the following?

Class1 x2 = x as Class1;
+1  A: 
((Class1)x).myDate
Chris Hutchinson
+4  A: 

Try the following:

DateTime.Compare( ((Class1)x).myDate, ((Class1)y).myDate); 
rtalbot
+3  A: 

It might just be the order of precedence on the casting vs. method call. Have you tried something like this?

DateTime.Compare( ((Class1)x).myDate, ((Class1)y).myDate);
Neil Fenwick
Indeed, it was. Terribly simple and I was unable to figure it out on my own. Thanks.
jehuty
+2  A: 

This might be splitting hairs, but you can do this:

DateTime.Compare((x as Class1).myDate, (y as Class1).myDate))

Mark Avenius
+1  A: 

Exception-less way:

Class1 c1 = null;
if (x is Class1) c1 = (Class1)x;
Jaroslav Jandek
Thanks for pointing that out!
jehuty
+1  A: 

If you want your Comparer to be stronly typed, use the generic version.

http://msdn.microsoft.com/en-us/library/8ehhxeaf.aspx

IComparer

So you'll implement it as:

public class MyComparer : IComparer<Class1>
{
    public int Compare( Class1 x, Class1 y )
    {
        // do comparison stuff here.
    }
}
MonkeyWrench
This truly seems the best solution - I'll go for it. Thanks.
jehuty
+1  A: 

You might want to do:

DateTime.Compare( ((Class1)x).myDate, (Class1)y).myDate);

The way you have it it is trying to cast the date field as Class1

Dismissile
Whoa...in the 30 seconds it took me to write my answer about 8 other people beat me :)
Dismissile
I just can't believe how simple it is!
jehuty
Sometimes it's the simplest things that give us the most trouble.
Dismissile
+2  A: 

The best solution would be to extend Comparer<Class1>.

Comparer<T>is an abstract class that implements both the generic and non-generic versions of IComparer. The advantage of extending it is that you don't have to implement the non-generic IComparer.Compare method; it is already implemented by the base-class sensibly.

public class Class1Comparer: Comparer<Class1>
{
   public override int Compare(Class1 x, Class1 y)
   {
      //null-checks here          
      return DateTime.Compare(x.myDate, y.myDate);
   }
}
Ani
+1  A: 

If you aren't going to have to compare heterogeneous types for some reason, I would always recommend combining the generic and more general (eh, hmm "generic" would be the correct English word there, silly .NET terminology) non-generic approaches in one class, calling into the generic from the non-generic. Most generic sorts will favour the generic method, but the non-generic will be there for use with a non-generic type (e.g. ArrayList) should it ever crop up. It's also a matter of 2 lines, and is logically sensible, so I don't hold with YAGNI in this case.

It's also a good idea to check for null arguments, even if you don't expect them. I've been caught a few times by failing to do so, and they could even be introduced "artificially" by some algorithms.

public class Class1Comparer : IComparer<Class1>, IComparer
{
  public int Compare(Class1 x, Class1 y)
  {
    if(x == null)
      return y == null ? 0 : -1;
    if(y == null)
      return 1;
    return DateTime.Compare(x.myDate, y.myDate);
  }
  public int Compare(object x, object y)
  {
    //This has no type-checking because you said above it isn't needed. I would normally add some just in case.
    return Compare((Class1)x, (Class1)y);
  }
}
Jon Hanna