ToUpperInvariant() - MSDN ошибочно по рекомендации?

В Рекомендации по использованию строк в .NET Framework, StringComparison OrdinalIgnoreCase рекомендуется для файлов, нечувствительных к регистру файлов. (Позвольте называть это утверждение A.)

Я могу согласиться с этим, потому что я могу создать два файла в одном каталоге:

é.txt
é.txt

Их имена файлов не совпадают, второй состоит из e и модификатора, поэтому на самом деле он имеет две буквы. (Вы можете попробовать себя с помощью copy-paste.)

Если бы имелось инвариантное сравнение культур (а не порядковое сравнение), NTFS не разрешала бы эти файлы, потому что в той же статье они объясняют, что в инвариантной культуре a + ̊ = å

Но в статье String.ToUpperInvariant() есть другая рекомендация: (Statement B.)

Если вам нужна строчная или прописная версия идентификатора операционной системы, например имя файла, named pipe или раздел реестра, используйте методы ToLowerInvariant или ToUpperInvariant.

Мне нужно создать коллекцию путей к файлу (фактически HashSet) для обнаружения дубликатов. Поэтому, если я буду подчиняться заявлению B при создании карты, я могу закончить с ложными срабатываниями, потому что вышеупомянутые имена файлов é.txt и é.txt будут считаться единичными. Правильно ли я понимаю, что утверждение B, найденное в MSDN, вводит в заблуждение? Или я что-то упускаю?

Я собираюсь создать библиотеку, желательно без известных ошибок с начала, поэтому я просто не хочу пренебрегать этим.

Обновление:

В заявлении 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. (источник)

Ответ 1

Ни верхний, ни нижний регистр не являются правильными, если вы хотите сравнить строки для равенства без учета регистра. В обоих вариантах есть символы, которые испортили это.

Правильный способ сравнения строк без учета регистра - использовать один из нечувствительных параметров StringComparison (вы знаете это).

Правильный способ использования структуры данных без учета регистра - использовать один из StringComparer.*IgnoreCase. Например:

new HashSet<string>(StringComparer.InvariantCultureIgnoreCase)

Не добавляйте строчные строки перед добавлением их в структуру данных. Я бы не смог это сделать в любом обзоре кода.

Если вам нужна строчная или прописная версия идентификатора операционной системы

Вам не нужна такая вещь. Это выражение не относится к вашему делу.