Perché il separatore di gruppo del numero di impostazioni cultura .NET "de-CH" è diverso a livello locale e in Azure?
Vedo un carattere Unicode diverso come separatore del gruppo di numeri per la cultura "de-CH" durante l'esecuzione su un desktop locale e in Azure.
Quando il codice seguente viene eseguito sul mio desktop in .NET Core 3.1 o .NET Framework 4.7.2, viene visualizzato 2019
come un apostrofo ma non è lo stesso.
Quando viene eseguito in Azure, ad esempio in https://try.dot.netoppure (leggermente modificato) in una funzione di Azure in esecuzione su .NET Core 3.1 (su un servizio app basato su Windows) risulta in 0027
un apostrofo ASCII standard.
using System;
using System.Linq;
using System.Globalization;
Console.WriteLine(((int)(CultureInfo
.GetCultureInfo("de-CH")
.NumberFormat
.NumberGroupSeparator
.Single())) // Just getting the single character as an int
.ToString("X4") // unicode value of that character
);
Il risultato di ciò è che il tentativo di analizzare la stringa 4'200.000
(dove l'apostrofo è Unicode 0027
) sul desktop locale utilizzando le impostazioni cultura "de-CH" non riesce, ma funziona in Azure.
Perché la differenza?
Risposte
Questo blog Microsoft di Shawn Steele spiega perché non dovresti fare affidamento sulla stabilità di un'impostazione culturale specifica (citato integralmente perché non è più online su MSDN):
https://web.archive.org/web/20190110065542/https://blogs.msdn.microsoft.com/shawnste/2005/04/05/culture-data-shouldnt-be-considered-stable-except-for-invariant/
I dati CultureInfo e RegionInfo rappresentano una preferenza culturale, regionale, amministratore o utente per le impostazioni culturali. Le applicazioni NON dovrebbero fare presupposti che si basano sulla stabilità di questi dati. L'unica eccezione (questa è una regola, quindi ovviamente c'è un'eccezione) è per CultureInfo.InvariantCulture. CultureInfo.InvariantCulture dovrebbe rimanere stabile, anche tra le versioni.
Ci sono molte ragioni per cui i dati culturali possono cambiare. Con Whidbey e Custom Cultures l'elenco si allunga un po '.
- La ragione più ovvia è che c'è un bug nei dati e abbiamo dovuto apportare una modifica. (Che ci crediate o no, facciamo degli errori ;-)) In questo caso i nostri utenti (e anche i vostri) vogliono dati culturalmente corretti, quindi dobbiamo correggere il bug anche se rompe le applicazioni esistenti.
- Un altro motivo è che le preferenze culturali possono cambiare. Ci sono molti modi in cui ciò può accadere, ma succede:
- La consapevolezza globale, lo scambio interculturale, il ruolo mutevole dei computer e così via possono influenzare una preferenza culturale.
- Trattati internazionali, commercio, ecc. Possono cambiare i valori. L'adozione dell'euro ha cambiato il simbolo della valuta di molti paesi in €.
- Anche le normative nazionali o regionali possono influire su questi valori.
- L'ortografia preferita delle parole può cambiare nel tempo.
- I formati di data preferiti, ecc. Possono cambiare.
- Potrebbero esistere più preferenze per una cultura. La scelta migliore preferita può quindi cambiare nel tempo.
- Gli utenti potrebbero aver sovrascritto alcuni valori, come i formati di data o ora. Questi possono essere richiesti senza override dell'utente, tuttavia si consiglia alle applicazioni di prendere in considerazione l'utilizzo di sostituzioni utente.
- Gli utenti o gli amministratori potrebbero aver creato una cultura sostitutiva, sostituendo i valori predefiniti comuni per una cultura con variazioni specifiche dell'azienda, regionali o di altro tipo dei dati standard.
- Alcune culture possono avere preferenze che variano a seconda dell'impostazione. Un'azienda potrebbe avere una forma più formale di un Internet Café.
- Un'azienda può richiedere un formato di data o ora specifico per l'intera organizzazione.
- Versioni diverse della stessa cultura personalizzata o una cultura personalizzata su una macchina e una cultura solo Windows su un'altra macchina.
Quindi, se formatti una stringa con un particolare formato di data / ora e poi provi ad analizzarla in un secondo momento, l'analisi potrebbe non riuscire se la versione è cambiata, se la macchina è cambiata, se la versione del framework è cambiata (dati più recenti) o se una cultura personalizzata era cambiato. Se è necessario rendere persistenti i dati in un formato affidabile, scegliere un metodo binario, fornire il proprio formato o utilizzare InvariantCulture.
Anche senza modificare i dati, ricordarsi di utilizzare Invariant è comunque una buona idea. Se hai diversi file. e, sintassi per qualcosa come 1,000.29, allora Parsing può essere confuso se un client si aspettava 1.000,29. Ho riscontrato questo problema con applicazioni che non si rendevano conto che la cultura di un utente sarebbe stata diversa dalla cultura dello sviluppatore. L'uso di Invariant o di un'altra tecnica risolve questo tipo di problema.
Ovviamente non puoi avere sia una visualizzazione "corretta" per l'utente corrente e un round trip perfetto se i dati della cultura cambiano. Quindi in genere consiglierei di conservare i dati utilizzando InvariantCulture o un altro formato non modificabile e utilizzando sempre le API di formattazione appropriate per la visualizzazione. La tua applicazione avrà i suoi requisiti, quindi considerali attentamente.
Si noti che per le regole di confronto (ordinamento / confronti), anche il comportamento Invariante può cambiare. Avrai bisogno di usare il Sort Versioning per aggirare questo se hai bisogno di ordinamenti costantemente stabili.
Se è necessario analizzare automaticamente i dati formattati per essere intuitivi, esistono due approcci:
- Consentire all'utente di specificare esplicitamente il formato utilizzato.
- Per prima cosa rimuovi tutti i caratteri eccetto le cifre, il segno meno e il separatore decimale dalla stringa prima di provare a analizzarlo. Nota che devi prima conoscere il separatore decimale corretto. Non c'è modo di indovinarlo correttamente e indovinare male potrebbe causare grossi problemi.
Ove possibile, cerca di evitare di analizzare numeri formattati per essere facili da usare. Invece, quando possibile, prova a richiedere numeri in un formato rigorosamente definito (invariante).