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<string>(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 的建议有误吗?的主要内容,如果未能解决你的问题,请参考以下文章