如何在 C# 中自定义 Comparer,以实现按中文拼音(a-z)来排序
1. 为何要自定义 Comparer
a. 先看如下代码
- class Program
- {
- public static void Main(string[] args)
- {
- List<string> words = new List<string>() { "我", "b", "中", "a", "是", "k", "人" };
- words.Sort();
- PrintResult(words);
- Console.ReadLine();
- }
- private static void PrintResult(IEnumerable<string> words)
- {
- if (words == null)
- {
- return;
- }
- int i = ;
- foreach (string item in words)
- {
- if (i > )
- {
- Console.Write(", ");
- }
- Console.Write(item);
- i++;
- }
- }
- }
b. 运行结果
结论:和我们预想的不一致!
2. 自定义 Comparer
CultureStringComparer.cs
- using System;
- using System.Globalization;
- public class CultureStringComparer : StringComparer
- {
- private CompareInfo _compareInfo;
- private CompareOptions _options;
- private bool _ignoreCase;
- public CultureStringComparer(CompareInfo compareInfo, CompareOptions options)
- {
- _compareInfo = compareInfo;
- _options = options;
- _ignoreCase = (options & CompareOptions.IgnoreCase) == CompareOptions.IgnoreCase ||
- (options & CompareOptions.OrdinalIgnoreCase) == CompareOptions.OrdinalIgnoreCase;
- }
- public override bool Equals(object obj)
- {
- if (!(obj is CultureStringComparer comparer))
- return false;
- if (_ignoreCase != comparer._ignoreCase)
- return false;
- return _compareInfo.Equals(comparer._compareInfo) && _options == comparer._options;
- }
- public override int GetHashCode()
- {
- int code = _compareInfo.GetHashCode();
- if (!_ignoreCase)
- return code;
- return ~code;
- }
- public override bool Equals(string x, string y) =>
- (
- string.Equals(x, y, StringComparison.Ordinal)
- || (x != null && y != null) && _compareInfo.Compare(x, y, _options) ==
- );
- public override int Compare(string x, string y)
- {
- if (string.Equals(x, y, StringComparison.Ordinal))
- return ;
- if (x == null)
- return -;
- if (y == null)
- return ;
- return _compareInfo.Compare(x, y, _options);
- }
- public override int GetHashCode(string obj)
- {
- if (obj == null)
- throw new ArgumentNullException(nameof(obj));
- return _compareInfo.GetHashCode(obj, _options);
- }
- }
测试示例
- class Program
- {
- public static void Main(string[] args)
- {
- CultureStringComparer cultureStringComparer = new CultureStringComparer(
- CompareInfo.GetCompareInfo("zh-cn"),
- CompareOptions.IgnoreCase);
- List<string> words = new List<string>()
- {
- "我", "b", "中", "a", "是", "k", "人"
- };
- words.Sort(cultureStringComparer);
- PrintResult(words);
- Console.ReadLine();
- }
- private static void PrintResult(IEnumerable<string> words)
- {
- if (words == null)
- {
- return;
- }
- int i = ;
- foreach (string item in words)
- {
- if (i > )
- {
- Console.Write(", ");
- }
- Console.Write(item);
- i++;
- }
- }
- }
运行结果
如何在 C# 中自定义 Comparer,以实现按中文拼音(a-z)来排序的更多相关文章
- 6.1 如何在spring中自定义xml标签
dubbo自定义了很多xml标签,例如<dubbo:application>,那么这些自定义标签是怎么与spring结合起来的呢?我们先看一个简单的例子. 一 编写模型类 package ...
- 如何在pyqt中自定义无边框窗口
前言 之前写过很多关于无边框窗口并给窗口添加特效的博客,按照时间线罗列如下: 如何在pyqt中实现窗口磨砂效果 如何在pyqt中实现win10亚克力效果 如何在pyqt中通过调用SetWindowCo ...
- C#如何在DataGridViewCell中自定义脚本编辑器
上一篇博文探讨了如何自定义DataGridViewColumn实现一个TreeViewColumn来在DataGridView控件中显示TreeView控件,其实我们还可以继续发挥想象,自定义其他的列 ...
- 如何在CODESOFT中自定义删除文档备料
CODESOFT 2015是先进的标签设计与集成软件.在使用CODESOFT制作条码标签时,为方便省时,我们可以事先创建自己的文档模板,保存它们以供将来使用.接下来,小编就讲讲CODESOFT 201 ...
- [VBA]用一个简单例子说明如何在Excel中自定义函数
Excel中的函数无疑是强大的,但是再强大的战士也有他脆弱的脚后跟[1].这两天在使用Excel的时候遇到了一个需求,要在某一个单元格里面自动计算今天是星期几(如显示 Today is Tuesday ...
- 如何在 Azure 中自定义 Windows 虚拟机
若要以快速一致的方式配置虚拟机 (VM),通常需要某种形式的自动化. 自定义 Windows VM 的一种常用方法是使用适用于 Windows 的自定义脚本扩展. 本教程介绍如何执行下列操作: 使用自 ...
- 如何在C#中自定义自己的异常
在C#中所有的异常类型都继承自System.Exception,也就是说,System.Exception是所有异常类的基类. 总起来说,其派生类分为两种:1. SystemException类: 所 ...
- 如何在pyqt中自定义SwitchButton
前言 网上有很多 SwitchButton 的实现方式,大部分是通过重写 paintEvent() 来实现的,感觉灵活性不是很好.所以希望实现一个可以联合使用 qss 来更换样式的 SwitchBut ...
- 如何在 pyqt 中自定义工具提示 ToolTip
前言 Qt 自带的工具提示样式不太好看,就算加了样式表也时不时会失效,同时工具提示没有阴影,看起来就更难受了.所以本篇博客将会介绍自定义工具提示的方法,效果如下图所示: 实现过程 工具提示其实就是一个 ...
随机推荐
- go-面向对象编程(上)
一个程序就是一个世界,有很多对象(变量) Golang 语言面向对象编程说明 1) Golang 也支持面向对象编程(OOP),但是和传统的面向对象编程有区别,并不是纯粹的面向对 象语言.所以我们说 ...
- JQ中的Ajax的封装
1.认识JQ中ajax的封装 jQ 对于ajax的封装有两层实现:$.ajax 为底层封装实现:基于 $.ajax ,分别实现了$.get 与$.post 的高层封装实现: 2.Ajax的底 ...
- DataGridView怎样实现添加、删除、上移、下移一行
场景 在Winform中使用DataGridView实现添加一行.删除一行.上移一行.下移一行. 注: 博客主页: https://blog.csdn.net/badao_liumang_qizhi ...
- XAF-内置初始化数据 (XPO)
Open the Updater.cs (Updater.vb) file, located in the MySolution.Module project's Database Update fo ...
- 创建Npm脚手架
1工具 l Npm ( https://nodejs.org/en/ ) l Yeoman (npm install -g yo) l generator-generator (npm inst ...
- Material 风格的搜索框MaterialSearchView的使用
大多数App中都有搜索的功能,虽然国内实实在在的遵循Google material design设计语言来设计的App实在不多,但个人感觉MD真的是非常值得研究,这次给大家介绍的是 Material ...
- Python类的定义、方法和属性使用
类用来描述具有相同的属性和方法的对象的集合.对于在类中定义的函数,称为方法.类变量不直接叫做类变量,称为属性. 1.类的定义 例子: class User(): pass 说明: (1)定义了一个类名 ...
- netcore codefirst生成数据库命令
1.程序通过nuget安装包 Microsoft.EntityFrameworkCore.Design 2.生成添加脚本 add-migration InitialCreate -Context AL ...
- Django2.0中基于正则表达式的路由机制(一)
1. 在urls.py的文件中导入操作正则表达式的方法:(新版的Django是使用path方法对URL进行路由分配) from django.contrib import admin from dj ...
- 无依赖单文件http-ftp文件服务器(py2)
网上看到的东东,居然在很合适堡垒机上传下载文件的场景. 这个只能在python2版本上跑, 我更改了自定义端口. 下次再改写个py3版本的. #!/usr/bin/env python "& ...