Как привести объект к типу класса в методе IComparer.Compare

Я реализую

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

из интерфейса IComparer. Я знаю, что объекты имеют тип Class1, и я знаю, что один из его членов является class1Instance.myDate, типа DateTime.

Я хочу сделать что-то вроде:

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

Но такой способ не работает. Есть ли альтернатива следующему?

Class1 x2 = x as Class1;

9 ответов

Решение

Это может быть просто порядок приоритета приведения типа против вызова метода. Вы пробовали что-то подобное?

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

Попробуйте следующее:

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

Лучшее решение было бы продлить Comparer<Class1>,

Comparer<T> абстрактный класс, который реализует как универсальные, так и неуниверсальные версии IComparer, Преимущество расширения заключается в том, что вам не нужно реализовывать неуниверсальный IComparer.Compare Способ; это уже разумно реализовано базовым классом.

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

Это может быть расщепление волос, но вы можете сделать это:

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

Без исключения способ:

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

Если вы хотите, чтобы ваш Comparer печатался строго, используйте универсальную версию.

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

IComparer

Таким образом, вы будете реализовывать это как:

public class MyComparer : IComparer<Class1>
{
    public int Compare( Class1 x, Class1 y )
    {
        // do comparison stuff here.
    }
}

Вы можете захотеть сделать:

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

Как у вас есть, он пытается привести поле даты к классу 1

((Class1)x).myDate

Если по какой-то причине вам не нужно сравнивать разнородные типы, я бы всегда рекомендовал комбинировать общие и более общие (да, хм, "универсальный" будет правильным английским словом, глупая терминология.NET) неуниверсальные подходы. в одном классе, вызывая в родовом из неуниверсального. Большинство родовых сортов предпочтут универсальный метод, но неуниверсальный будет там для использования с неуниверсальным типом (например, ArrayList) если это когда-нибудь всплывет. Это также вопрос двух строк, и это логически разумно, так что в этом случае я не придерживаюсь YAGNI.

Также рекомендуется проверять наличие нулевых аргументов, даже если вы их не ожидаете. Несколько раз меня ловили, если я этого не делал, и некоторые алгоритмы могли даже вводить их "искусственно".

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);
  }
}
Другие вопросы по тегам