Как я могу заставить мой универсальный компаратор (IComparer) обрабатывать пустые значения? - PullRequest
8 голосов
/ 31 января 2011

Я пытаюсь написать универсальный объектный компаратор для сортировки, но я заметил, что он не обрабатывает случай, когда одно из сравниваемых значений является нулевым.Когда объект нулевой, я хочу, чтобы он рассматривал его так же, как пустую строку.Я попытался установить нулевые значения в String.Empty, но затем я получаю сообщение об ошибке «Объект должен иметь тип String» при вызове CompareTo () для него.

public int Compare(T x, T y)
{
    PropertyInfo propertyInfo = typeof(T).GetProperty(sortExpression);
    IComparable obj1 = (IComparable)propertyInfo.GetValue(x, null);
    IComparable obj2 = (IComparable)propertyInfo.GetValue(y, null);

    if (obj1 == null) obj1 = String.Empty; // This doesn't work!
    if (obj2 == null) obj2 = String.Empty; // This doesn't work!

    if (SortDirection == SortDirection.Ascending)
        return obj1.CompareTo(obj2);
    else
        return obj2.CompareTo(obj1);
}

Я застрял сэто сейчас!Любая помощь будет оценена.

Ответы [ 4 ]

18 голосов
/ 31 января 2011

Вы не можете рассматривать ваш T как пустую строку, если ваш T не был эффективно ограничен как строка.То, что вы должны сделать, это иметь план для сравнения нулей.Такие как

if (obj1 == null && obj2 == null)
   return 0;
else if (obj1 == null)
   return -1;
else if (obj2 == null)
   return 1;
else 
   return obj1.CompareTo(obj2);
2 голосов
/ 31 января 2011
if (SortDirection == SortDirection.Ascending)
    return Comparer<T>.Default.Compare(obj1, obj2);
else
    return Comparer<T>.Default.Compare(obj2, obj1);
0 голосов
/ 31 января 2011
IComparable obj1 = (IComparable)propertyInfo.GetValue(x, null) ?? "";
IComparable obj2 = (IComparable)propertyInfo.GetValue(y, null) ?? "";

Это в основном означает, что obj1 теперь будет значением propertyInfo.GetValue (x, null) или, если это будет нулевым, obj1 будет "".

Или если проблемав том, что GetValue дает сбой на нуле, вы можете сделать что-то вроде:

IComparable obj1 = "";
try { obj1 = (IComparable)propertyInfo.GetValue(x, null); } catch {}
0 голосов
/ 31 января 2011

Поскольку T является универсальным типом, вы не можете присвоить ему значение String; Вы можете только присвоить ему значение типа T. Если вы собираетесь использовать это только для сравнения строк, используйте String вместо T. В противном случае добавьте нулевую проверку и определите, где в порядке null должен упасть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...