CultureInfo.InvariantCulture anlamı ne?


178

Ben böyle bir metin dizesi var:

var foo = "FooBar";

Ben denilen ikinci bir dize bildirmek barve bu ilk ve dördüncü karakter ilk fooyapmak istiyorum, bu yüzden böyle yapmak:

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

Bu beklendiği gibi çalışıyor, ancak ReSharperCulture.InvariantCulture parantezlerimin içine koymamı tavsiye ediyor , bu yüzden bu çizgi şöyle bitiyor:

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

Bu ne anlama geliyor ve programımın çalışma şeklini etkiler mi?



39
5 saniyelik cevabı arayanlar için: CultureInfo.InvariantCulture, "Umurumda değil, kültürün ilk ehil olmasını istemiyorum. Şimdi aptal şeyi kullanmama izin ver" anlamına gelir.
Andrew

5
@Andrew Tüm MS belgelerini yeniden yazabilir misiniz, lütfen?
Yatrix

3
@Yatrix Evet, elbette. Ben isterdim! Kim ödüyor?
Andrew

Yanıtlar:


155

Tüm kültürler tarihler ve ondalık / para birimi değerleri için aynı biçimi kullanmaz.

Bu, dize olarak saklanan giriş değerlerini (okuma) dönüştürürken sizin için önemli olacaktır . DateTime , float, doubleveya decimal. Yukarıda belirtilen veri türlerini görüntüleme veya depolama için dizelere (yazma) biçimlendirmeye çalışmanız da önemli olacaktır .

Tarihlerinizin ve ondalık / para birimi değerlerinizin vaktinden önce hangi belirli kültürü olacağını biliyorsanız, söz konusu CultureInfoözelliği (ör.CultureInfo("en-GB") ) . Örneğin, bir kullanıcı girişi bekliyorsanız.

CultureInfo.InvariantCultureEğer biçimlendirme veya kullanıcının yerel ayarları yazılım bağımsız bir parça ayrıştırılabilir olması gereken bir dize ayrıştırma takdirde maddi kullanılır.

Varsayılan değer, CultureInfo.InstalledUICulturevarsayılan CultureInfo'nun yürütme işletim sisteminin ayarlarına bağlı olması içindir. Bu yüzden her zaman kültür bilgisinin niyetinize uyduğundan emin olmalısınız ( iyi bir kılavuz için Martin'in cevabına bakınız ).


3
"tr-TR" olsa da, aslında sistem ayarlarınıza bağlı olabileceğini düşünüyorum.
Tracker1

44
Varsayılan değer değil en-US. Yerel kültür. Ve InvariantCultureyerel sistemden bağımsız kültür nötr biçimlendirme istediğinizde kullanılır. Örneğin, metin tabanlı dosya formatlarıyla çalışırken.
CodesInChaos

23
@CodesInChaos yorumuna eklemek için: Varsayılan değerin CultureInfo ("en-US") olduğu iddiası yanlıştır. Ayrıca, CultureInfo.InvariantCulture özelliği, tarihlerinizin ve ondalık / para birimi değerlerinin hangi kültür biçiminde olacağından emin olmadığınız zaman kullanılır. Kafa karıştırıcıdır. Mevcut olanı, değişmezi veya belirli bir kültürü kullanmak bilinçli bir karar olması gereken bir şeydir ve yanlış anlarsanız (ABD dışındaki) kullanıcılarınızı yabancılaştırabilirsiniz. "Emin değilseniz" değişmez kültürü kullanmamalısınız. Önceden emin olmalısın.
Martin Liversage

3
-1 diğer yorumlarda bahsedilen sorunlar nedeniyle. Martin'in cevabı daha faydalıdır çünkü her kültürü ne zaman kullanacağınızı ve kullanmamanızı söyler.
Ed Greaves

"yalnızca Amerikan İngilizcesinde çalışıyorsanız, endişelenmenize gerek yoktur.": Yanlış, yalnızca Amerikan İngilizcesinde çalışıyor olabilirsiniz, ancak yazılım "en-GB" veya "de -DE "sunucusu, o zaman bir fark yaratacak, ayrıca müşterinin kültürünü alabilir (eğer web.config dosyasında söylüyorsanız) ve bu da" en-US "olmayabilir ...
Stefan Steiger

152

Sayılar, tarihler ve saatler dizgilere biçimlendirildiğinde veya dizelerden ayrıştırıldığında, nasıl yapıldığını belirlemek için bir kültür kullanılır. Örneğin, baskın en-USkültürde şu sicim temsillerine sahipsiniz:

  • 1.000.000,00 - iki basamaklı bir kesire sahip bir milyon
  • 29.01.2013 - bu yayının tarihi

Benim culture ( da-DK) değerleri şu dize temsil var:

  • 1.000.000,00 - iki basamaklı kesirli bir milyon
  • 29-01-2013 - bu yayının tarihi

Windows işletim sisteminde, kullanıcı sayıların ve tarih / saatlerin nasıl biçimlendirileceğini bile özelleştirebilir ve ayrıca işletim sisteminin kültüründen başka bir kültür seçebilir. Kullanılan biçimlendirme, kullanıcının nasıl olması gerektiğinin seçimidir.

Bu nedenle, örneğin kullanılarak ToStringveya görüntülenecek bir değeri biçimlendirdiğinizde veya String.Formatveya bir dizeden ayrıştırıldığında DateTime.Parseveya Decimal.Parsevarsayılan kullanarak kullanmaktır CultureInfo.CurrentCulture. Bu, kullanıcının biçimlendirmeyi kontrol etmesini sağlar.

Bununla birlikte, çok sayıda dize biçimlendirme ve ayrıştırma aslında uygulama ve kullanıcı arasında değil, uygulama ve bazı veri formatı (örneğin bir XML veya CSV dosyası) arasında değiş tokuş edilen dizelerdir. Bu durumda kullanmak istemezsiniz CultureInfo.CurrentCultureçünkü biçimlendirme ve ayrıştırma farklı kültürlerle yapılırsa kırılabilir. Bu durumda CultureInfo.InvariantCulture( en-USkültüre dayalı) kullanmak istersiniz . Bu, değerlerin sorunsuz bir şekilde geri dönmesini sağlar.

ReSharper size uyarı verir sebebi bazı uygulama yazarları istenmeyen sonuçlara yol açabilir bu ayrım habersiz ama onların çünkü bu keşfetmek asla olmasıdır CultureInfo.CurrentCultureDİR en-USolarak aynı davranışa sahip CultureInfo.InvariantCulture. Ancak, uygulama biçimlendirmek için bir kültür kullanma ve başvuruyu ayrıştırmak için başka bir kültür kullanma şansının bulunduğu başka bir kültürde kullanılır kullanılmaz.

Özetlemek gerekirse:

  • CultureInfo.CurrentCultureBir kullanıcı dizesini biçimlendiriyorsanız veya ayrıştırıyorsanız (varsayılan) seçeneğini kullanın .
  • CultureInfo.InvariantCultureBir yazılım parçası tarafından ayrıştırılması gereken bir dizeyi biçimlendiriyorsanız veya ayrıştırıyorsanız kullanın .
  • Nadiren belirli bir ulusal kültür kullanın, çünkü kullanıcı biçimlendirme ve ayrıştırma işleminin nasıl yapıldığını kontrol edemez.

1
Son noktaya gelince, "Nadiren belirli bir ulusal kültür kullanın ...", para birimi biçimlendirme bir istisna olur mu? Örneğin, DecimalABD Doları'nda belirli bir değer içeren bir değişkenim varsa en-US, Euro olarak bir sayıya benzeyen bir sonuç almadığından emin olmak için bunu görüntülerken bir istisna yapmak ve kültür olarak kullanmak ister miyim? Denedim CultureInfo.InvariantCulture , ama para birimi işareti için ¤bunu aldım, bu yüzden doğru yol olduğundan emin değilim.
Jeff B

1
@JeffBridgman: Tavsiyem sadece genel tavsiye niteliğindedir ve özel durumunuz için geçerli olmayabilir. Ancak, ondalık noktasını (virgül veya nokta) görüntüleme şeklinizin, kullanıcının denetlediği (örneğin kullanımı CultureInfo.CurrentCulture) bir şey olması gerektiğini düşünürüm . Bir sayıyı görüntülemek için ek olarak para birimine ihtiyacınız varsa, belki de tutarlı bir şekilde yapmalısınız, yani a CultureInfokullanmayın ve bunun yerine üç harfli para birimi kodunu kullanın USD 1,234.56. O zaman bir para birimini bir kültüre eşleme sorunlarına girmezsiniz.
Martin Liversage

26

Microsoft'a göre:

CultureInfo.InvariantCulture özelliği ne nötr ne de spesifik bir kültürdür. Kültüre duyarsız olan üçüncü bir kültür türüdür. İngilizce dili ile ilişkilidir, ancak bir ülke veya bölge ile ilişkilendirilmez.

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

Yani InvariantCulture "en-US" kültürüne similair ama tam olarak aynı değil. Eğer yazarsanız:

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"

o zaman s1 ve s2 similair formatına sahip olur, ancak InvariantCulture önde gelen sıfırlar ekler ve "en-US" AM veya PM kullanır.

Bu nedenle, örneğin bir metin dosyasına tarih kaydederken veya verileri ayrıştırdığınızda InvariantCulture dahili kullanım için daha iyidir. Son kullanıcıya veri (tarih, para birimi ...) sunduğunuzda belirli bir CultureInfo daha iyidir.


3
Onaylamak için örnek kodunuzu çalıştırdım: InvariantCulture, ISO 8601 ilk yıl formatını izlemek yerine Amerikan MM / gg / yyyy kullanır. Buna rağmen, insan tüketimi için değil, taşınabilir depolama ve mekanik işleme için tasarlanmıştır. Nasıl kafa karıştırıcı
Max Barraclough

4

Sayılar (ondalık basamaklar, miktarlarda virgül) gibi şeyler için, genellikle belirli kültürde tercih edilir.

Bunu yapmanın uygun bir yolu onu kültür seviyesinde (Almanca için) şu şekilde ayarlamaktır:

Thread.CurrentThread.CurrentCulture.NumberFormat = new CultureInfo("de").NumberFormat;

4

JetBrains makul bir açıklama sunuyor ,

"Veri yapılarının metne geçici olarak dönüştürülmesi büyük ölçüde mevcut kültüre bağlıdır ve kod yerel ayarı orijinal geliştiriciden farklı olan bir makinede yürütüldüğünde istenmeyen sonuçlara neden olabilir. Belirsizlikleri önlemek için ReSharper sizi uyarır kodda böyle bir sorunun olabileceği herhangi bir örnek. "

ancak yalnızca İngilizce olacağını bildiğim bir sitede çalışıyorsam, öneriyi görmezden gelirim.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.