c# - 使用 IComparer 基于多个字段进行排序
问题描述
我使用下面的代码对List<DataAccessViewModel>
列表进行排序。
这是排序顺序:
- 优先分数
- 名称
- 名称
- 名称
它按预期工作。
public int Compare(DataAccessViewModel x, DataAccessViewModel y)
{
if (x == null || y == null)
{
return 0;
}
return x.CompareTo(y);
}
public int CompareTo(DataAccessViewModel mod)
{
int retval = (int)(this.PriorityScore?.CompareTo(mod.PriorityScore));
if(retval != 0)
return retval;
else
{
retval = (this.MName ?? "zzzzzzzzzzzzz").CompareTo(mod.MName ?? "zzzzzzzzzzzzz");
if (retval != 0)
return retval;
else
{
retval = (this.CName ?? "zzzzzzzzzzzzz").CompareTo(this.CName ?? "zzzzzzzzzzzzz");
if (retval != 0)
return retval;
else
retval = (this.FName ?? "zzzzzzzzzzzzz").CompareTo(this.FName ?? "zzzzzzzzzzzzz");
}
}
return retval;
}
但是代码对我来说看起来很笨拙。有没有更好的方法或者是这样吗?
解决方案
当前代码存在问题:
public int Compare(DataAccessViewModel x, DataAccessViewModel y)
{
if (x == null || y == null)
{
return 0;
}
...
因为null
等于任何值,所以所有值都相等:
a == null, null == b => a == b
这不是您要实施的规则。我建议这样的事情
using System.Linq;
...
// static: we don't want "this"
public static int TheCompare(DataAccessViewModel x, DataAccessViewModel y) {
// Special cases, nulls
if (ReferenceEquals(x, y)) // if references are shared, then equal
return 0;
if (null == x) // let null be smaller than any other value
return -1;
if (null == y)
return 1;
// How we compare strings
static int MyCompare(string left, string right) =>
ReferenceEquals(left, right) ? 0
: null == left ? 1 // null is greater than any other string
: null == right ? -1
: string.Compare(left, right);
// Func<int> for lazy computation
return new Func<int>[] {
() => x.PriorityScore?.CompareTo(y.PriorityScore) ?? -1,
() => MyCompare(x.MName, y.MName),
() => MyCompare(x.CName, y.CName),
() => MyCompare(x.FName, y.FName),
}
.Select(func => func())
.FirstOrDefault(value => value != 0);
}
然后对于接口我们有
public int CompareTo(DataAccessViewModel other) => TheCompare(this, other);
// I doubt if you want to implement both IComparable<T> and
// IComparer<T> but you can easily do it
public int Compare(DataAccessViewModel x, DataAccessViewModel y) =>
TheCompare(x, y);
推荐阅读
- python - 在 Tkinter 的文件夹中动态初始化 Frames
- java - 从 javafx 中的 Stage 类创建新对象时抛出异常
- latex - 更改 LaTex 中的附录格式
- javascript - moment.js 返回 "NaN" for moment("03/13/2020", "YYYY-MM-DD")
- c++ - 如何使用父类指针中未在父类中定义的子类方法?
- c# - 将多页 TIFF 拆分为多个 JPG 文件
- node.js - 为什么使用Node和OracleDB时Query Stream在处理完所有异步项之前就结束了
- java - TreeSet 和 Hibernate 的问题 - 无法转换为 java.lang.Comparable
- excel - VBA继续运行,我必须按“esc”结束代码
- gremlin - 在 tinkerpop 中获取已保存中间节点的路径