结合多个Linq OrderBy实现IComparer

max*_*axp 5 c# sorting icomparer

我的问题是我总是想以某种方式订购对象的集合。

例如:

class foo{
public string name {get;set;}
public DateTime date {get;set;}
public int counter {get;set;}
}
Run Code Online (Sandbox Code Playgroud)

...

IEnumerable<foo> dosomething(foo[] bar){ 
return bar.OrderBy(a=>a.name).ThenBy(a=>a.date).ThenBy(a=>a.counter);
}
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是,它一直都在漫长地处理排序顺序。一个好的解决方案似乎只是创建一个实现的类IComparer<foo>,这意味着我可以做:

IEnumerable<foo> dosomething(foo[] bar){ 
return bar.OrderBy(a=>a, new fooIComparer())
}
Run Code Online (Sandbox Code Playgroud)

问题是,该实现的命令方法如下

...

public int Compare(foo x, foo y){ }
Run Code Online (Sandbox Code Playgroud)

意味着它在非常细微的基础上进行比较。

当前的实现(虽然我正在编写伪代码,但可能会起作用)

public int Compare(foo x, foo y){
if (x==y)
  return 0;
var order = new []{x,y}.OrderBy(a=>a.name).ThenBy(a=>a.date).ThenBy(a=>a.counter);
  return (order[0] == x) ? -1 : -1;//if x is first in array it is less than y, else it is greater
}
Run Code Online (Sandbox Code Playgroud)

这不是完全有效,另一个可以提供更整洁的解决方案吗?理想情况下完全不使用Compare(x,y)方法?

Tim*_*ter 2

您必须实现IComparable<foo>并比较所有属性:

class foo: IComparable<foo>, IComparer<foo>
{
    public string name { get; set; }
    public DateTime date { get; set; }
    public int counter { get; set; }

    public int Compare(foo x, foo y)
    {
        if (x == null || y == null) return int.MinValue;
        if (x.name != y.name)
            return StringComparer.CurrentCulture.Compare(x.name, y.name);
        else if (x.date != y.date)
            return x.date.CompareTo(y.date);
        else if (x.counter != y.counter)
            return x.counter.CompareTo(y.counter);
        else
            return 0;
    }

    public int CompareTo(foo other)
    {
        return Compare(this, other);
    }
}
Run Code Online (Sandbox Code Playgroud)

那么你可以OrderBy这样使用:

var ordered = foos.OrderBy(f => f).ToList();
Run Code Online (Sandbox Code Playgroud)