Как привести объект к типу класса в методе 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
Если по какой-то причине вам не нужно сравнивать разнородные типы, я бы всегда рекомендовал комбинировать общие и более общие (да, хм, "универсальный" будет правильным английским словом, глупая терминология.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);
}
}