记一次系统迁移遇到的中文字符串排序问题

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记一次系统迁移遇到的中文字符串排序问题相关的知识,希望对你有一定的参考价值。

背景

不久前,迁移了一个 framework 项目到 .net core 上面,部署也从 Windows 的 IIS 到 linux 的容器化。

期间遇到了一个关于中文字符串排序的问题,在这里记录一下。

复现与处理

下面这段代码就是出现问题的代码。

var list = new List<string>
 
    "阿莫西林", "阿司匹林", "阿卡波糖"
;

list.Sort();

foreach (var item in list)

    Console.WriteLine(item);

大家觉得,排序后的结果会是怎么样的呢?

这个排序结果其实取决于当前环境的 CultureInfo,因为 list.Sort() 最后会调用 Array.Sort<T>(Array keys, Array? items, int index, int length, IComparer? comparer),没有显式的传递 comparer 参数,这个时候就会用到 Comparer.Default,这个 default 的构造函数就传入了 CultureInfo.CurrentCulture

大体调用逻辑可以参考下面的 4 个 github 链接

https://github.com/dotnet/runtime/blob/dfe1076090adad6990747e6abed8bf6699371877/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs#L1046 https://github.com/dotnet/runtime/blob/dfe1076090adad6990747e6abed8bf6699371877/src/libraries/System.Private.CoreLib/src/System/Array.cs#L1817 https://github.com/dotnet/runtime/blob/dfe1076090adad6990747e6abed8bf6699371877/src/libraries/System.Private.CoreLib/src/System/Array.cs#L1850 https://github.com/dotnet/runtime/blob/dfe1076090adad6990747e6abed8bf6699371877/src/libraries/System.Private.CoreLib/src/System/Collections/Comparer.cs#L21

知道这个的话,就可以来验证一下了。

本地调试输出如下:


基于 mcr.microsoft.com/dotnet/runtime:6.0-bullseye-slim 镜像,

docker build -t sort:v1 -f .\\Dockerfile .
docker run --rm sort:v1

放到容器下面输出如下:

可以看到,默认的是为空的,也就是没有任何指定。

由于 bullseye-slim 镜像已经包含了 icu 相关的库,所以可以直接指定 LC_ALL 或 LANG 为 zh_CN 即可。

docker run --rm -e LC_ALL=zh_CN sort:v1
# 或
docker run --rm -e LANG=zh_CN sort:v1

这个时候的输出就是和本地调试一致的了。

所以最后的解决方案是 添加多一个环境变量 来解决这个问题。迁移虽然简单,一些小细节还是要注意的!!

如果是用 alpine 镜像的话,要注意安装 icu 相关的库。

参考资料

  • https://learn.microsoft.com/zh-cn/previous-versions/bb688122(v=msdn.10)?redirectedfrom=MSDN

  • https://learn.microsoft.com/zh-cn/dotnet/api/system.globalization.cultureinfo?view=net-7.0

  • https://github.com/dotnet/runtime/issues/59193

以上是关于记一次系统迁移遇到的中文字符串排序问题的主要内容,如果未能解决你的问题,请参考以下文章

SQLServer记一次数据迁移-标识重复的简单处理

记一次Azure VM 迁移(不同的订阅之间)

初码-Azure系列-记一次MySQL数据库向Azure的迁移

Oracle -- 记一次ADG库迁移过程小结 -- 上篇(ADG建库)

记一次堆排序使用的真实案例

记一次阿里云ECS服务器图片资源迁移至 阿里云 oss