如何使用comparer对2个或更多sort排序进行排序

时间:2011-06-16 12:34:35

标签: c#

我必须使用自编码比较器对对象列表进行排序。

myObjectList.Sort(new MyComparer(_sortExpression, _sortDirection));

如果第一个表达式上的值相等,我如何附加第二个表达式和方向以进行排序?

我是指例如:按姓氏排序,然后按名字相等。但我必须使用自己的比较器。

myObjectList.Sort(
   new MyComparer(new string[]{_exp1, _exp2}, new string[]{_dir1, _dir2}));

提前致谢! 维德勋爵

2 个答案:

答案 0 :(得分:3)

您可以定义一个允许链式比较器的扩展方法,如下所示:

public static class ComparerExtensions
{
    public static IComparer<T> ThenBy<T>(this IComparer<T> comparer1,
                                         IComparer<T> comparer2)
    {
        return new ChainedComparer<T>(comparer1, comparer2);
    }

    private class ChainedComparer<T> : IComparer<T>
    {
        private readonly IComparer<T> comparer1;
        private readonly IComparer<T> comparer2;

        public ChainedComparer(IComparer<T> comparer1,
                               IComparer<T> comparer2)
        {
            this.comparer1 = comparer1;
            this.comparer2 = comparer2;
        }

        public int Compare(T x, T y)
        {
            int result = this.comparer1.Compare(x, y);
            if (result == 0) result = this.comparer2.Compare(x, y);
            return result;
        }
    }
}

用法:

var comparer = new MyComparer(_sortExpression1, _sortDirection1).ThenBy(
               new MyComparer(_sortExpression2, _sortDirection2));

myObjectList.Sort(comparer);

这将按第一个比较器对列表进行排序,如果两个项目相等,则由第二个比较器排序。


替代解决方案:

class ChainComparer<T> : IComparer<T>
{
    private readonly IEnumerable<IComparer<T>> comparers;

    public ChainComparer(params IComparer<T>[] comparers)
    {
        this.comparers = comparers;
    }

    public int Compare(T x, T y)
    {
        int result = 0;
        foreach (var comparer in this.comparers)
        {
            result = comparer.Compare(x, y);
            if (result != 0) break;
        }
        return result;
    }
}

用法:

myObjectList.Sort(new ChainComparer<MyClass>(
    new MyComparer(_sortExpression1, _sortDirection1),
    new MyComparer(_sortExpression2, _sortDirection2)));

答案 1 :(得分:0)

您可以将两个字符串连接在一起,并对该值进行正常排序。它会给你相同的结果。或者如果你可以使用链接,你可以这样做:

myObjectList.OrderBy(p => p.LastName).ThenBy(p => p.FirstName);

还有OrderByDescending和ThenByDescending方法。