jehuty
jehuty

Reputation: 538

How to cast 'object' to Class type on IComparer.Compare method

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;

Upvotes: 1

Views: 2407

Answers (9)

Jon Hanna
Jon Hanna

Reputation: 113332

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);
  }
}

Upvotes: 1

Ani
Ani

Reputation: 113452

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);
   }
}

Upvotes: 3

Dismissile
Dismissile

Reputation: 33071

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

Upvotes: 1

MonkeyWrench
MonkeyWrench

Reputation: 1839

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.
    }
}

Upvotes: 1

Jaroslav Jandek
Jaroslav Jandek

Reputation: 9563

Exception-less way:

Class1 c1 = null;
if (x is Class1) c1 = (Class1)x;

Upvotes: 1

Mark Avenius
Mark Avenius

Reputation: 13947

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

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

Upvotes: 2

Neil Fenwick
Neil Fenwick

Reputation: 6184

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);

Upvotes: 4

rtalbot
rtalbot

Reputation: 1645

Try the following:

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

Upvotes: 4

Chris Hutchinson
Chris Hutchinson

Reputation: 9212

((Class1)x).myDate

Upvotes: 1

Related Questions