WPF ListCollectionView自定义排序的IComparer两种实现方案选型
方案选型结论
优先选择第二种方案:直接让原有MyComparer类同时实现IComparer<string>(泛型)和IComparer(非泛型)接口,当前场景下单独编写适配器属于冗余设计。
两种方案对比
第二种方案(单类实现双接口)优势
- 代码结构更简洁,无需额外新增类,减少项目维护成本,没有不必要的封装层级
- 符合.NET官方实现惯例:.NET 内置的所有比较器实现(比如
StringComparer、各类值类型的默认比较器)都采用了同时实现泛型+非泛型IComparer的方式,符合通用开发规范,可读性更高 - 性能略优:避免了适配器层的额外调用开销,虽然该开销极小,但属于无意义的冗余消耗
同时实现双接口的弊端
弊端非常有限,仅包含两个可规避的小问题:
- 非泛型
Compare方法需要做类型强转,如果传入非string类型参数会抛出转换异常。但在你的WPF DataGrid绑定场景下,ListCollectionView排序时传入的参数就是你绑定的字符串字段值,只要确保数据源对应字段类型正确,该风险完全可控 - 若后续该比较器需要在仅允许纯泛型比较器的场景复用,非泛型方法属于额外的无关实现。你可以通过显式实现非泛型接口的方式规避该问题,非泛型方法只会在变量被声明为
IComparer类型时才会被调用,不会污染泛型场景的调用
适配器方案的适用场景
适配器方案仅适合你无权修改MyComparer源码的场景:比如MyComparer是第三方类库提供的实现,无法调整其接口继承关系,才需要额外写适配器做兼容。你当前可以直接修改MyComparer的实现,完全不需要额外引入适配器类。
推荐实现代码
public class MyComparer : IComparer<string>, IComparer { // 对外暴露的泛型实现 public int Compare(string a, string b) { // 你的自定义排序逻辑 } // 显式实现非泛型接口,仅内部被ListCollectionView调用时触发 int IComparer.Compare(object a, object b) { return Compare((string)a, (string)b); } }
使用时直接赋值即可:
listCollectionView.CustomSort = new MyComparer();
内容的提问来源于stack exchange,提问作者Zserbinator
相关产品推荐
相关产品推荐

