1. 为何要自定义 Comparer

a. 先看如下代码

  1. class Program
  2. {
  3. public static void Main(string[] args)
  4. {
  5. List<string> words = new List<string>() { "我", "b", "中", "a", "是", "k", "人" };
  6. words.Sort();
  7. PrintResult(words);
  8. Console.ReadLine();
  9. }
  10.  
  11. private static void PrintResult(IEnumerable<string> words)
  12. {
  13. if (words == null)
  14. {
  15. return;
  16. }
  17. int i = ;
  18. foreach (string item in words)
  19. {
  20. if (i > )
  21. {
  22. Console.Write(", ");
  23. }
  24. Console.Write(item);
  25. i++;
  26. }
  27. }
  28. }

b. 运行结果

结论:和我们预想的不一致!

2. 自定义 Comparer

CultureStringComparer.cs

  1. using System;
  2. using System.Globalization;
  3.  
  4. public class CultureStringComparer : StringComparer
  5. {
  6. private CompareInfo _compareInfo;
  7. private CompareOptions _options;
  8. private bool _ignoreCase;
  9.  
  10. public CultureStringComparer(CompareInfo compareInfo, CompareOptions options)
  11. {
  12. _compareInfo = compareInfo;
  13. _options = options;
  14. _ignoreCase = (options & CompareOptions.IgnoreCase) == CompareOptions.IgnoreCase ||
  15. (options & CompareOptions.OrdinalIgnoreCase) == CompareOptions.OrdinalIgnoreCase;
  16. }
  17.  
  18. public override bool Equals(object obj)
  19. {
  20. if (!(obj is CultureStringComparer comparer))
  21. return false;
  22.  
  23. if (_ignoreCase != comparer._ignoreCase)
  24. return false;
  25.  
  26. return _compareInfo.Equals(comparer._compareInfo) && _options == comparer._options;
  27. }
  28.  
  29. public override int GetHashCode()
  30. {
  31. int code = _compareInfo.GetHashCode();
  32. if (!_ignoreCase)
  33. return code;
  34.  
  35. return ~code;
  36. }
  37.  
  38. public override bool Equals(string x, string y) =>
  39. (
  40. string.Equals(x, y, StringComparison.Ordinal)
  41. || (x != null && y != null) && _compareInfo.Compare(x, y, _options) ==
  42. );
  43.  
  44. public override int Compare(string x, string y)
  45. {
  46. if (string.Equals(x, y, StringComparison.Ordinal))
  47. return ;
  48.  
  49. if (x == null)
  50. return -;
  51.  
  52. if (y == null)
  53. return ;
  54.  
  55. return _compareInfo.Compare(x, y, _options);
  56. }
  57.  
  58. public override int GetHashCode(string obj)
  59. {
  60. if (obj == null)
  61. throw new ArgumentNullException(nameof(obj));
  62.  
  63. return _compareInfo.GetHashCode(obj, _options);
  64. }
  65. }

测试示例

  1. class Program
  2. {
  3. public static void Main(string[] args)
  4. {
  5. CultureStringComparer cultureStringComparer = new CultureStringComparer(
  6. CompareInfo.GetCompareInfo("zh-cn"),
  7. CompareOptions.IgnoreCase);
  8. List<string> words = new List<string>()
  9. {
  10. "我", "b", "中", "a", "是", "k", "人"
  11. };
  12. words.Sort(cultureStringComparer);
  13.  
  14. PrintResult(words);
  15. Console.ReadLine();
  16. }
  17.  
  18. private static void PrintResult(IEnumerable<string> words)
  19. {
  20. if (words == null)
  21. {
  22. return;
  23. }
  24. int i = ;
  25. foreach (string item in words)
  26. {
  27. if (i > )
  28. {
  29. Console.Write(", ");
  30. }
  31. Console.Write(item);
  32. i++;
  33. }
  34. }
  35. }

运行结果

如何在 C# 中自定义 Comparer,以实现按中文拼音(a-z)来排序的更多相关文章

  1. 6.1 如何在spring中自定义xml标签

    dubbo自定义了很多xml标签,例如<dubbo:application>,那么这些自定义标签是怎么与spring结合起来的呢?我们先看一个简单的例子. 一 编写模型类 package ...

  2. 如何在pyqt中自定义无边框窗口

    前言 之前写过很多关于无边框窗口并给窗口添加特效的博客,按照时间线罗列如下: 如何在pyqt中实现窗口磨砂效果 如何在pyqt中实现win10亚克力效果 如何在pyqt中通过调用SetWindowCo ...

  3. C#如何在DataGridViewCell中自定义脚本编辑器

    上一篇博文探讨了如何自定义DataGridViewColumn实现一个TreeViewColumn来在DataGridView控件中显示TreeView控件,其实我们还可以继续发挥想象,自定义其他的列 ...

  4. 如何在CODESOFT中自定义删除文档备料

    CODESOFT 2015是先进的标签设计与集成软件.在使用CODESOFT制作条码标签时,为方便省时,我们可以事先创建自己的文档模板,保存它们以供将来使用.接下来,小编就讲讲CODESOFT 201 ...

  5. [VBA]用一个简单例子说明如何在Excel中自定义函数

    Excel中的函数无疑是强大的,但是再强大的战士也有他脆弱的脚后跟[1].这两天在使用Excel的时候遇到了一个需求,要在某一个单元格里面自动计算今天是星期几(如显示 Today is Tuesday ...

  6. 如何在 Azure 中自定义 Windows 虚拟机

    若要以快速一致的方式配置虚拟机 (VM),通常需要某种形式的自动化. 自定义 Windows VM 的一种常用方法是使用适用于 Windows 的自定义脚本扩展. 本教程介绍如何执行下列操作: 使用自 ...

  7. 如何在C#中自定义自己的异常

    在C#中所有的异常类型都继承自System.Exception,也就是说,System.Exception是所有异常类的基类. 总起来说,其派生类分为两种:1. SystemException类: 所 ...

  8. 如何在pyqt中自定义SwitchButton

    前言 网上有很多 SwitchButton 的实现方式,大部分是通过重写 paintEvent() 来实现的,感觉灵活性不是很好.所以希望实现一个可以联合使用 qss 来更换样式的 SwitchBut ...

  9. 如何在 pyqt 中自定义工具提示 ToolTip

    前言 Qt 自带的工具提示样式不太好看,就算加了样式表也时不时会失效,同时工具提示没有阴影,看起来就更难受了.所以本篇博客将会介绍自定义工具提示的方法,效果如下图所示: 实现过程 工具提示其实就是一个 ...

随机推荐

  1. 【CF528E】Triangles 3000(计算几何)

    [CF528E]Triangles 3000(计算几何) 题面 CF 平面上有若干条直线,保证不平行,不会三线共点. 求任选三条直线出来围出的三角形的面积的期望. 题解 如果一定考虑直接计算这个三角形 ...

  2. HttpClient 如何设置超时时间

    今天分享一个巨坑,就是 HttpClient.这玩意有多坑呢?就是每个版本都变,近日笔者深受其害. 先看一下代码,我要发送请求调用一个c++接口. public static String doPos ...

  3. Spring Cloud Gateway-自定义异常处理

    前提 我们平时在用SpringMVC的时候,只要是经过DispatcherServlet处理的请求,可以通过@ControllerAdvice和@ExceptionHandler自定义不同类型异常的处 ...

  4. WPF——如何为项目设置全局样式。

    在项目中,需要为所有的Button.TextBox设置一个默认的全局样式,一个个的为多个控件设置相同的样式显然是不明智的.在WPF中可以通过资源设置全局样式,主要有俩种方法: 1.第一种就是先写好按钮 ...

  5. Z从壹开始前后端分离【 .NET Core2.0/3.0 +Vue2.0 】框架之四 || Swagger的使用 3.2

    本文梯子 本文3.0版本文章 前言 一.swagger的一般用法 0.设置swagger页面为首页——开发环境 1.设置默认直接首页访问 —— 生产环境 2.为接口添加注释 3.对 Model 也添加 ...

  6. vue-路由-显示名称

    显示名称 方式1: <div id="app"> <!-- 分析: --> <!-- 1. 我们要监听到 文本框数据的改变,这样才能知道 什么时候去拼 ...

  7. angular版聊天室|仿微信界面IM聊天|NG2+Node聊天实例

    一.项目介绍 运用angular+angular-cli+angular-router+ngrx/store+rxjs+webpack+node+wcPop等技术实现开发的仿微信angular版聊天室 ...

  8. 搭建RTMP直播流服务器

    最近项目比较紧张,所以没什么时间写博客,正好这几天没什么事,赶紧记录下自己最近所学. 环境配置 服务器选用 服务器我选择的是小鸟云 ,原因很简单,他的个人用户有3个月免费使用时间. 服务器环境 Win ...

  9. JavaScript—数据可视化(ECharts)

    Echarts具有丰富的图表,可以说是数据可视化的神器: 1.下载Echarts 官网下载地址:https://echarts.baidu.com/index.html 2.Echarts引用案例—柱 ...

  10. eclipse C++ 配置自动提示

    转:http://www.cnblogs.com/myitm/archive/2010/12/17/1909194.html 定位到:Windows→Preferences→Java→Editor→C ...