ToUpperInvariant() – MSDN 的建议有误吗?

Posted

技术标签:

【中文标题】ToUpperInvariant() – MSDN 的建议有误吗?【英文标题】:ToUpperInvariant() – is MSDN wrong on its recommendation? 【发布时间】:2015-09-23 13:04:25 【问题描述】:

在Best Practices for Using Strings in the .NET Framework 中,建议将StringComparison OrdinalIgnoreCase 用于不区分大小写的文件路径。 (我们称它为语句 A。)

我可以同意,因为我可以在同一个目录中创建两个文件:

é.txt
é.txt

它们的文件名不一样,第二个是由e和修饰符组成的,所以实际上是两个字母。 (您可以尝试使用复制粘贴。)

如果存在不变文化比较(而不是序数比较),NTFS 不会允许这些文件,因为在同一篇文章中他们解释说,在不变文化a + ̊ = å

但在String.ToUpperInvariant() 的文章中有不同的建议:(声明 B.)

如果您需要操作系统标识符的小写或大写版本,例如文件名、命名管道或注册表项,请使用 ToLowerInvariant 或 ToUpperInvariant 方法。

我需要创建文件路径集合(实际上是HashSet)来检测重复项。因此,如果我在创建地图时遵循语句 B,我可能会以误报结束,因为上述文件名 é.txté.txt 将被视为一个。我是否正确理解 MSDN 中的陈述 B 具有误导性?还是我错过了什么?

我即将建立一个库,最好从一开始就没有已知的错误,所以我不想忽视这一点。

更新:

语句 B 似乎还有一个问题:实际上无法使用 ToLowerInvariant()。原因(我引用最佳实践文章):DO: Use ToUpperInvariant rather than ToLowerInvariant when normalizing strings for comparison. 实际原因:There is a small range of characters that do not roundtrip, and going to lowercase will make these characters unavailable. (source)

【问题讨论】:

我不完全确定“操作系统标识符的小写或大写版本”是否与“操作系统标识符到小写或大写版本的明确映射”相同。它也可能意味着“将操作系统标识符映射到非唯一的小写或大写版本,无论系统的区域设置如何,都将以相同的方式工作”。 OT,但谁知道你的库是做什么的:NTFS 还允许在文件名中使用 :*?。只是 Windows 不支持它。在 Linux 下的 NTFS 上创建这样的文件非常容易。 @O.R.Mapper - 阅读该声明的好方法......在这种情况下,它看起来合乎逻辑。另一方面,他们可以不提及文件名,也可以添加关于(非)唯一性的简短说明。 【参考方案1】:

当您想在不区分大小写的情况下比较字符串是否相等时,大写和小写都不正确。在这两种变体中,都有一些字符会搞砸。

不区分大小写比较字符串的正确方法是使用不区分大小写的StringComparison 选项之一(你知道的)。

不区分大小写地使用数据结构的正确方法是使用StringComparer.*IgnoreCase 之一。例如:

new HashSet<string>(StringComparer.InvariantCultureIgnoreCase)

在将它们添加到数据结构之前不要大写字符串。在任何代码审查中我都会失败。

如果您需要操作系统标识符的小写或大写版本

你不需要这样的东西。此声明不适用于您的情况。

【讨论】:

因此,对于 NTFS 文件名,这意味着 new HashSet&lt;string&gt;(StringComparer.OrdinalIgnoreCase)(或只是 OrdinalCase,取决于特定情况下如何切换 NTFS 区分大小写)。 我不知道NTFS用什么样的比较。它可以配置。每个 NTFS 卷上都有一个隐藏文件,用于存储 Unicode 大小写映射表。我想这可能是任意的。不确定它在实践中是什么。 是的,我知道...这意味着我们实际上可能需要类似 NtfsIgnoreCase 的比较,根据隐藏的 $UpCase 文件的内容工作:) 见this answer of mine(简称:文件名使用OrdinalIgnoreCase)。 @LucasTrzesniewski – 我真的见过 :) 以及 this 和 this 值得注意的问答。最后,我使用Dictionary(Of T1, T2)(StringComparer.OrdinalIgnoreCase) 来满足我的特定需求。

以上是关于ToUpperInvariant() – MSDN 的建议有误吗?的主要内容,如果未能解决你的问题,请参考以下文章

Java 等价于不变文化

14 字符字符串和文本处理

vs2015 msdn的离线帮助文档怎么使用

怎样下载msdn本地文档

什么是msdn

安装过vs2015后,msdn library帮助手册 在哪儿