如何使我的通用比较器(IComparer)处理空值?

时间:2011-01-31 14:58:36

标签: c# .net sorting icomparer

我正在尝试编写一个用于排序的通用对象比较器,但我注意到它不处理其中一个值比较为null的实例。当一个对象为null时,我希望它对待它与空字符串相同。我已经尝试将null值设置为String.Empty,但是当我在上面调用CompareTo()时,我得到一个“Object必须是String类型”的错误。

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 个答案:

答案 0 :(得分:17)

除非你的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);

答案 1 :(得分:2)

if (SortDirection == SortDirection.Ascending)
    return Comparer<T>.Default.Compare(obj1, obj2);
else
    return Comparer<T>.Default.Compare(obj2, obj1);

答案 2 :(得分:0)

由于T是通用类型,因此您无法为其分配String值;您只能为其指定T类型的值。如果您只是用它来比较字符串,请使用String代替T。否则,添加空检查并确定null应该落在哪里。

答案 3 :(得分:0)

IComparable obj1 = (IComparable)propertyInfo.GetValue(x, null) ?? "";
IComparable obj2 = (IComparable)propertyInfo.GetValue(y, null) ?? "";

这基本上意味着obj1现在将是propertyInfo.GetValue(x,null)的值,或者如果恰好为null,则obj1将为“”。

或者如果问题是GetValue在null上崩溃,你可以做类似的事情:

IComparable obj1 = "";
try { obj1 = (IComparable)propertyInfo.GetValue(x, null); } catch {}