4

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

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

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

4

2 回答 2

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);
}

主要问题是您只检查valueAIComparable并且 if valueA == null- 比较返回对象相等,无论valueB. 当可空值被装箱时(这正是这里发生的事情),它由实际值或null.

于 2012-07-07T15:35:00.563 回答
0

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

当我对任一字符串值进行排序时,效果很好。但是,当我对任一可为空的 DateTime 进行排序时?值,它排序一个 DateTime? 值正确,但它“丢失”了字符串值的信息!

我留下了一个按指定日期时间排序的列表?值,并且仍然包含另一个 DateTime?值,但清空字符串值?

这里有什么想法吗?

于 2015-01-23T22:44:55.797 回答