2015-09-23 20 views
11

In Best Practices for Using Strings in the .NET Framework, StringComparison OrdinalIgnoreCase è consigliato per percorsi di file senza distinzione tra maiuscole e minuscole. (Chiamiamolo Dichiarazione A.)ToUpperInvariant() - MSDN è errato sulla sua raccomandazione?

Posso essere d'accordo con questo, perché posso creare due file nella stessa directory:

é.txt 
é.txt 

I loro nomi non sono gli stessi, seconda unità è composta da e e modificatore, quindi in realtà ha due lettere. (Puoi provare tu stesso usando il copia-incolla.)

Se ci fosse un confronto di culture invarianti (e non un confronto ordinale) in effetti, NTFS non permetterebbe questi file, perché nello stesso articolo spiegano che nella cultura invariante a + ̊ = å

Ma in articolo sul String.ToUpperInvariant() c'è raccomandazione diversa: (Statement B.)

Se è necessario il minuscolo o versione maiuscola di un identificatore del sistema operativo, come ad esempio un nome di file, named pipe, o chiave di registro, utilizzare i metodi ToLowerInvariant o ToUpperInvariant.

Ho bisogno di creare raccolta del percorso file (in realtà HashSet) per rilevare i duplicati. Quindi, se obbedirò alla dichiarazione B durante la creazione della mappa, potrei finire con i falsi positivi, perché i nomi di file sopracitati é.txt e é.txt saranno considerati come uno. Sto capendo correttamente che l'affermazione B trovata in MSDN è fuorviante? O mi sta sfuggendo qualcosa?

Sto per creare una libreria, preferibilmente senza errori noti dall'inizio, quindi semplicemente non voglio trascurarlo.

Aggiornamento:

Normativa B sembra avere un problema più: ToLowerInvariant() non può essere effettivamente utilizzata. La ragione (cito le migliori pratiche articolo): DO: Use ToUpperInvariant rather than ToLowerInvariant when normalizing strings for comparison. vera ragione: There is a small range of characters that do not roundtrip, and going to lowercase will make these characters unavailable. (source)

+3

Non sono del tutto sicuro che "la versione in minuscolo o in maiuscolo di un identificatore del sistema operativo" sia identica a "una mappatura non ambigua di un identificatore del sistema operativo in una versione minuscola o maiuscola". Potrebbe anche significare "una mappatura di un identificatore del sistema operativo su una versione minuscola o maiuscola non univoca che funzionerà allo stesso modo indipendentemente dalle impostazioni locali del sistema". –

+0

OT, ma chissà cosa fa la tua libreria: NTFS permette anche ':', '* o'? 'Nei nomi dei file. È solo Windows che non lo supporta. È abbastanza facile creare tali file su NTFS sotto Linux. –

+0

@ O.R.Mapper - un buon modo di leggere questa affermazione ... In questo contesto sembra logico. D'altra parte, potrebbero omettere di menzionare i nomi dei file o aggiungere una breve nota sulla (non-) unicità. – miroxlav

risposta

5

Né il maiuscolo né lettere minuscole sono corretti quando si desidera confrontare le stringhe per l'uguaglianza è case-sensitive. In entrambe le varianti ci sono personaggi che incasinano questo.

Il modo corretto per confrontare stringhe senza distinzione tra maiuscole e minuscole consiste nell'utilizzare una delle opzioni non sensibili StringComparison (lo sapete).

Il modo corretto di utilizzare una struttura dati in modo insensibile consiste nell'utilizzare uno dei StringComparer.*IgnoreCase. Per esempio:

new HashSet<string>(StringComparer.InvariantCultureIgnoreCase) 

fare non stringhe maiuscole prima di aggiungerli a una struttura di dati. Non lo farei in nessuna revisione del codice.

Se è necessario il minuscolo o versione maiuscola di un identificatore del sistema operativo

Non è necessario, come cosa. Questa affermazione non si applica al tuo caso.

+0

Quindi, nel caso di nomi di file NTFS, ciò significa 'nuovo HashSet (StringComparer.OrdinalIgnoreCase)' (o solo 'OrdinalCase', a seconda di come viene spostata la distinzione tra maiuscole e minuscole nel caso specifico). – miroxlav

+0

Non conosco il tipo di confronto utilizzato da NTFS. Può essere configurato. C'è un file nascosto su ogni volume NTFS che memorizza la tabella di mappatura dei casi Unicode. Immagino che potrebbe essere arbitrario. Non so cosa sia in pratica. – usr

+0

Sì, lo so ... Significa che potremmo effettivamente aver bisogno di qualcosa come il confronto 'NtfsIgnoreCase', basato sul contenuto di quel file' $ UpCase' nascosto :) – miroxlav