如何更正通用排序代码以排序可空类型

时间:2012-07-07 15:00:00

标签: c# .net generics sorting nullable

我们一直在使用此方法对通用List<>进行排序。最近,当T中的target属性是可空类型(十进制?)时,我们注意到了不正确的结果。任何想法如何纠正?

public void SortList<T>(List<T> dataSource, string fieldName, SortDirection sortDirection)
{
    PropertyInfo propInfo = typeof(T).GetProperty(fieldName);
    Comparison<T> compare = delegate(T a, T b)
    {
        bool asc = sortDirection == SortDirection.Ascending;
        object valueA = asc ? propInfo.GetValue(a, null) : propInfo.GetValue(b, null);
        object valueB = asc ? propInfo.GetValue(b, null) : propInfo.GetValue(a, null);

        return valueA is IComparable ? ((IComparable)valueA).CompareTo(valueB) : 0;
    };
    dataSource.Sort(compare);
}

以上代码来自Phil Hustead的文章“按对象属性名称排序通用列表和IEnumerables” http://www.codeproject.com/Articles/27851/Sorting-Generic-Lists-and-IEnumerables-by-Object-P

例如,我的 Employee 对象具有可为空的十进制属性 Hours

可以逗留的时间 107,null,8,152,64,null 排序到 8,null,64,null,107,152

我认为空值应该排序到列表的开头或结尾。

2 个答案:

答案 0 :(得分:4)

将您的方法更改为

public static void SortList<T>(List<T> dataSource, string fieldName, SortDirection sortDirection)
{
    PropertyInfo propInfo = typeof(T).GetProperty(fieldName);
    Comparison<T> compare = delegate(T a, T b)
    {
        bool asc = sortDirection == SortDirection.Ascending;
        object valueA = asc ? propInfo.GetValue(a, null) : propInfo.GetValue(b, null);
        object valueB = asc ? propInfo.GetValue(b, null) : propInfo.GetValue(a, null);

        if(valueA == null)
        {
            if(valueB == null)
            {
                return 0;
            }
            else
            {
                return asc ? -1 : 1;
            }
        }
        if(valueB == null)
        {
            return asc ? 1 : -1;
        }

        return valueA is IComparable ? ((IComparable)valueA).CompareTo(valueB) : 0;
    };
    dataSource.Sort(compare);
}

主要问题是,您只检查valueA IComparable,如果valueA == null - 比较返回对象相等,无论valueB中的内容是什么。当可以为空的值加框时(这正是这里发生的事情),它由实际值或null表示。

答案 1 :(得分:0)

支持可空值的上述(最终)示例适用于我的列表,但仅适用于某些情况。我的CustomType包含四个字段,其中两个是字符串类型,其中两个是DateTime? (可空)类型。

当我对任一字符串值进行排序时,它的效果很好。但是,当我对可以为空的DateTime进行排序时?值,它对一个DateTime进行排序?价值得当,但它失去了&#34;字符串值的信息!

我是否按照指定的DateTime排序了List?值,还包含其他DateTime?值,但清空字符串值?

这里有什么想法吗?