Was bedeutet CultureInfo.InvariantCulture?

177

Ich habe eine Textfolge wie folgt:

var foo = "FooBar";

Ich möchte eine zweite Zeichenfolge mit dem Namen deklarieren barund dies gleich dem ersten und vierten Zeichen meines ersten Zeichens machen foo, also mache ich das so:

var bar = foo[0].ToString() + foo[3].ToString();

Dies funktioniert wie erwartet, aber ReSharper rät mir, Culture.InvariantCulturein meine Klammern zu setzen , sodass diese Zeile wie folgt endet:

var bar = foo[0].ToString(CultureInfo.InvariantCulture)
        + foo[3].ToString(CultureInfo.InvariantCulture);

Was bedeutet das und wird es sich auf die Ausführung meines Programms auswirken?

JMK
quelle
2
Siehe diese SO-Frage: stackoverflow.com/questions/8492449/…
msigman
38
Für diejenigen, die nach der 5-Sekunden-Antwort suchen: CultureInfo.InvariantCulture bedeutet "Es ist mir egal, ich möchte nicht, dass Kultur überhaupt involviert ist. Jetzt lass mich das dumme Ding benutzen."
Andrew
5
@ Andrew Können Sie alle MS-Dokumente umschreiben, bitte?
Yatrix
3
@ Yatrix Ja, sicher. Ich würde es gerne tun! Wer zahlt?
Andrew

Antworten:

154

Nicht alle Kulturen verwenden dasselbe Format für Datumsangaben und Dezimal- / Währungswerte.

Dies wird für Sie relevante, wenn Sie Eingabewerte konvertieren (Lesen) , die als Strings gespeichert sind DateTime, float, doubleoder decimal. Es ist auch wichtig, wenn Sie versuchen, die oben genannten Datentypen zur Anzeige oder Speicherung in Zeichenfolgen (Schreiben) zu formatieren .

Wenn Sie im Voraus wissen, in welcher bestimmten Kultur sich Ihre Daten und Dezimal- / Währungswerte befinden, können Sie diese bestimmte CultureInfoEigenschaft (dh CultureInfo("en-GB")) verwenden. Zum Beispiel, wenn Sie eine Benutzereingabe erwarten.

Die CultureInfo.InvariantCultureEigenschaft wird verwendet, wenn Sie eine Zeichenfolge formatieren oder analysieren, die von einer Software unabhängig von den lokalen Einstellungen des Benutzers analysiert werden soll.

Der Standardwert ist CultureInfo.InstalledUICultureso, dass die Standard-CultureInfo von den Einstellungen des ausführenden Betriebssystems abhängt. Aus diesem Grund sollten Sie immer sicherstellen, dass die Kulturinformationen Ihrer Absicht entsprechen ( eine gute Richtlinie finden Sie in Martins Antwort ).

JohnB
quelle
3
"en-US", ich denke, es kann tatsächlich von Ihren Systemeinstellungen abhängen.
Tracker1
44
Der Standardwert ist nicht en-US. Es ist die lokale Kultur. Und InvariantCulturewird verwendet, wenn Sie eine kulturneutrale Formatierung wünschen, die vom lokalen System unabhängig ist. Zum Beispiel bei der Arbeit mit textbasierten Dateiformaten.
CodesInChaos
23
So fügen Sie einen Kommentar zu @CodesInChaos hinzu: Die Behauptung, dass der Standardwert CultureInfo ("en-US") ist, ist einfach falsch. Außerdem ist die Anweisung Die CultureInfo.InvariantCulture-Eigenschaft wird verwendet, wenn Sie nicht im Voraus sicher sind, in welchem ​​Kulturformat Ihre Daten und Dezimal- / Währungswerte vorliegen . Die Verwendung der aktuellen, der invarianten oder einer bestimmten Kultur sollte eine bewusste Entscheidung sein. Wenn Sie etwas falsch machen, können Sie Ihre (nicht US-amerikanischen) Benutzer entfremden. Sie sollten die invariante Kultur nicht verwenden, wenn Sie "unsicher" sind. Sie müssen im Voraus sicher sein.
Martin Liversage
3
-1 aufgrund der in anderen Kommentaren genannten Probleme. Die Antwort von Martin ist hilfreicher, weil sie Ihnen sagt, wann Sie jede Kultur verwenden und nicht verwenden sollen.
Ed Greaves
"Wenn Sie ausschließlich in amerikanischem Englisch arbeiten, brauchen Sie sich darüber keine Sorgen zu machen.": Falsch, Sie arbeiten möglicherweise ausschließlich in amerikanischem Englisch, aber die Software läuft möglicherweise auf einem "en-GB" oder einem "de" -DE "Server, dann wird es einen Unterschied machen, und es kann die Kultur des Clients übernehmen (wenn Sie dies in der Datei web.config sagen), und das ist möglicherweise auch nicht" en-US "...
Stefan Steiger
151

Wenn Zahlen, Datums- und Uhrzeitangaben in Zeichenfolgen formatiert oder aus Zeichenfolgen analysiert werden, wird eine Kultur verwendet, um zu bestimmen, wie dies erfolgt. ZB in der dominanten en-USKultur haben Sie diese String-Darstellungen:

  • 1.000.000,00 - eine Million mit einem zweistelligen Bruchteil
  • 29.01.2013 - Datum dieser Veröffentlichung

In meiner Kultur ( da-DK) haben die Werte diese Zeichenfolgendarstellung:

  • 1.000.000,00 - eine Million mit einem zweistelligen Bruchteil
  • 29-01-2013 - Datum dieser Veröffentlichung

Im Windows-Betriebssystem kann der Benutzer sogar die Formatierung von Zahlen und Datum / Uhrzeit anpassen und eine andere Kultur als die Kultur seines Betriebssystems auswählen. Die verwendete Formatierung ist die Wahl des Benutzers, wie es sein sollte.

Also , wenn Sie einen Wert formatieren , um den Benutzer angezeigt werden , indem zum Beispiel ToStringoder String.Formatoder aus einer Zeichenfolge analysiert unter Verwendung von DateTime.Parseoder Decimal.Parseder Standard ist das verwenden CultureInfo.CurrentCulture. Dadurch kann der Benutzer die Formatierung steuern.

Bei vielen Formatierungen und Analysen von Zeichenfolgen werden jedoch keine Zeichenfolgen zwischen der Anwendung und dem Benutzer ausgetauscht, sondern zwischen der Anwendung und einem bestimmten Datenformat (z. B. einer XML- oder CSV-Datei). In diesem Fall möchten Sie nicht verwenden, CultureInfo.CurrentCultureda das Formatieren und Parsen mit verschiedenen Kulturen unterbrochen werden kann. In diesem Fall möchten Sie verwenden CultureInfo.InvariantCulture(was auf der en-USKultur basiert ). Dies stellt sicher, dass die Werte problemlos umrunden können.

Der Grund , dass ReSharper gibt Ihnen die Warnung ist , dass einige Anwendungs Autoren nicht bewusst diese Unterscheidung sind die zu unerwünschten Ergebnissen führen kann , aber sie nie entdecken , weil sie CultureInfo.CurrentCultureheißt , en-USdie als das gleiche Verhalten hat CultureInfo.InvariantCulture. Sobald die Anwendung jedoch in einer anderen Kultur verwendet wird, in der die Möglichkeit besteht, eine Kultur zum Formatieren und eine andere zum Parsen zu verwenden, kann die Anwendung unterbrochen werden.

Um es zusammenzufassen:

  • Verwenden Sie CultureInfo.CurrentCulture(Standardeinstellung), wenn Sie eine Benutzerzeichenfolge formatieren oder analysieren.
  • Verwenden CultureInfo.InvariantCultureSie diese Option, wenn Sie eine Zeichenfolge formatieren oder analysieren, die von einer Software analysiert werden soll.
  • Verwenden Sie selten eine bestimmte nationale Kultur, da der Benutzer nicht steuern kann, wie formatiert und analysiert wird.
Martin Liversage
quelle
1
Wäre die Währungsformatierung in Bezug auf den letzten Punkt "Verwenden Sie selten eine bestimmte nationale Kultur ..." eine Ausnahme? Wenn ich beispielsweise eine DecimalVariable habe, die einen bestimmten Wert in US-Dollar enthält, möchte ich dann eine Ausnahme machen und en-USals Kultur verwenden, wenn ich sie anzeige, um sicherzustellen, dass ich kein Ergebnis erhalte, das wie eine Zahl in Euro aussieht? Ich habe es versucht CultureInfo.InvariantCulture , habe es aber für den Währungsmarker bekommen ¤, daher bin ich mir nicht sicher, ob das der richtige Weg ist.
Jeff B
1
@ JeffBridgman: Mein Rat ist nur ein allgemeiner Rat und gilt möglicherweise nicht für Ihren speziellen Fall. Ich würde jedoch denken, dass die Art und Weise, wie Sie den Dezimalpunkt (Komma oder Punkt) anzeigen, vom Benutzer gesteuert werden sollte (z CultureInfo.CurrentCulture. B. Verwendung ). Wenn Sie zusätzlich zur Anzeige einer Zahl die Währung benötigen, sollten Sie dies möglicherweise auf konsistente Weise tun, dh nicht a verwenden CultureInfound stattdessen den dreistelligen Währungscode wie verwenden USD 1,234.56. Dann geraten Sie nicht in die Probleme, eine Währung einer Kultur zuzuordnen.
Martin Liversage
26

Laut Microsoft:

Die CultureInfo.InvariantCulture-Eigenschaft ist weder eine neutrale noch eine bestimmte Kultur. Es ist eine dritte Art von Kultur, die kulturunempfindlich ist. Es ist mit der englischen Sprache verbunden, aber nicht mit einem Land oder einer Region.

(von http://msdn.microsoft.com/en-us/library/4c5zdc6a(vs.71).aspx )

InvariantCulture ähnelt also der Kultur "en-US", ist aber nicht genau dasselbe. Wenn Sie schreiben:

var d = DateTime.Now;
var s1 = d.ToString(CultureInfo.InvariantCulture);   // "05/21/2014 22:09:28"
var s2 = d.ToString(new CultureInfo("en-US"));       // "5/21/2014 10:09:28 PM"

dann haben s1 und s2 das gleiche Format, aber InvariantCulture fügt führende Nullen hinzu und "en-US" verwendet AM oder PM.

InvariantCulture ist also besser für den internen Gebrauch geeignet, wenn Sie beispielsweise ein Datum in einer Textdatei speichern oder Daten analysieren. Und eine bestimmte CultureInfo ist besser, wenn Sie dem Endbenutzer Daten (Datum, Währung ...) präsentieren.

Happybits
quelle
3
Ich habe Ihren Beispielcode ausgeführt, um zu bestätigen: InvariantCulture verwendet amerikanisches MM / TT / JJJJ, anstatt dem ISO 8601-Format für das erste Jahr zu folgen. Trotzdem ist es eher für die tragbare Lagerung und mechanische Verarbeitung als für den menschlichen Verzehr gedacht. Wie verwirrend
Max Barraclough
4

Für Dinge wie Zahlen (Dezimalstellen, Kommas in Beträgen) werden sie normalerweise in der spezifischen Kultur bevorzugt.

Ein geeigneter Weg, dies zu tun, wäre, es auf kultureller Ebene (für Deutsch) wie folgt einzustellen:

Thread.CurrentThread.CurrentCulture.NumberFormat = new CultureInfo("de").NumberFormat;
Turing Maschine
quelle
4

JetBrains bieten eine vernünftige Erklärung ,

"Die Ad-hoc-Konvertierung von Datenstrukturen in Text hängt weitgehend von der aktuellen Kultur ab und kann zu unbeabsichtigten Ergebnissen führen, wenn der Code auf einem Computer ausgeführt wird, dessen Gebietsschema sich von dem des ursprünglichen Entwicklers unterscheidet. Um Unklarheiten zu vermeiden, warnt ReSharper Sie alle Fälle im Code, in denen ein solches Problem auftreten kann. "

Wenn ich jedoch an einer Website arbeite, von der ich weiß, dass sie nur auf Englisch verfügbar ist, ignoriere ich den Vorschlag einfach.

Neil Thompson
quelle