CultureInfo.InvariantCARM nghĩa là gì?


177

Tôi có một chuỗi văn bản như vậy:

var foo = "FooBar";

Tôi muốn khai báo một chuỗi thứ hai được gọi barvà làm cho chuỗi này bằng với ký tự thứ nhất và thứ tư của ký tự đầu tiên của tôi foo, vì vậy tôi làm như vậy:

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

Điều này hoạt động như mong đợi, nhưng ReSharper đang khuyên tôi nên đặt Culture.InvariantCulturetrong dấu ngoặc của mình, vì vậy dòng này kết thúc như vậy:

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

Điều này có nghĩa là gì, và nó sẽ ảnh hưởng đến cách chương trình của tôi chạy?



38
Đối với những người tìm kiếm câu trả lời 5 giây: CultureInfo.InvariantCARM có nghĩa là "Tôi không quan tâm, tôi không muốn văn hóa liên quan đến nơi đầu tiên. Bây giờ hãy để tôi sử dụng điều ngu ngốc."
Andrew

5
@Andrew Bạn có thể viết lại tất cả các tài liệu của MS không?
Yatrix

3
@Yatrix Vâng, điều chắc chắn. Tôi rất thích! Ai trả tiền?
Andrew

Câu trả lời:


154

Không phải tất cả các nền văn hóa đều sử dụng cùng một định dạng cho ngày và giá trị thập phân / tiền tệ.

Điều này sẽ quan trọng cho bạn khi bạn đang chuyển đổi các giá trị đầu vào (đọc) được lưu trữ như dây đàn để DateTime, float, doublehoặc decimal. Nó cũng sẽ có vấn đề nếu bạn cố gắng định dạng các loại dữ liệu nói trên thành chuỗi (ghi) để hiển thị hoặc lưu trữ.

Nếu bạn biết văn hóa cụ thể mà ngày và giá trị thập phân / tiền tệ của bạn sẽ đi trước thời đại, bạn có thể sử dụng CultureInfotài sản cụ thể đó (nghĩa là CultureInfo("en-GB")). Ví dụ: nếu bạn mong đợi một đầu vào của người dùng.

Các CultureInfo.InvariantCulturetài sản được sử dụng nếu bạn đang định dạng hoặc phân tích một chuỗi mà nên parseable bởi một mảnh độc lập phần mềm của thiết lập địa phương của người dùng.

Giá trị mặc định là CultureInfo.InstalledUICulturevì vậy CultureInfo mặc định phụ thuộc vào cài đặt của hệ điều hành. Đây là lý do tại sao bạn phải luôn đảm bảo thông tin văn hóa phù hợp với ý định của bạn (xem câu trả lời của Martin để có hướng dẫn tốt).


3
"en-US" mặc dù, tôi nghĩ rằng nó thực sự có thể phụ thuộc vào cài đặt hệ thống của bạn.
Tracker1

44
Giá trị mặc định là không en-US. Đó là văn hóa địa phương. Và InvariantCultuređược sử dụng khi bạn muốn định dạng văn hóa trung lập độc lập với hệ thống cục bộ. Ví dụ khi làm việc với các định dạng tệp dựa trên văn bản.
CodeInChaos

23
Để thêm vào nhận xét @CodesInChaos: Khiếu nại rằng Giá trị mặc định là CultureInfo ("en-US") đơn giản là sai. Ngoài ra, câu lệnh Thuộc tính CultureInfo.InvariantCARM được sử dụng khi bạn không chắc chắn trước thời hạn văn hóa định dạng ngày và giá trị thập phân / tiền tệ của bạn sẽ gây nhầm lẫn. Sử dụng hiện tại, bất biến hoặc một nền văn hóa cụ thể là một quyết định có ý thức và nếu bạn hiểu sai, bạn có thể xa lánh người dùng (không phải Hoa Kỳ) của mình. Bạn không nên sử dụng văn hóa bất biến nếu bạn "không chắc chắn". Bạn cần chắc chắn trước thời hạn.
Martin Liversage

3
-1 do các vấn đề được đề cập trong các ý kiến ​​khác. Câu trả lời của Martin hữu ích hơn vì nó cho bạn biết khi nào nên sử dụng và không sử dụng từng nền văn hóa.
Ed Greaves

"Nếu bạn đang làm việc độc quyền bằng tiếng Anh Mỹ, thì bạn không cần phải lo lắng về điều đó.": Không chính xác, bạn có thể làm việc độc quyền bằng tiếng Anh Mỹ, nhưng phần mềm có thể chạy trên "en-GB" hoặc "de -DE "máy chủ, sau đó nó sẽ tạo ra sự khác biệt, cộng với nó có thể lấy văn hóa của khách hàng (nếu bạn nói như vậy trong tệp web.config) và đó có thể không phải là" en-US "...
Stefan Steiger

151

Khi số, ngày và thời gian được định dạng thành chuỗi hoặc được phân tích cú pháp từ chuỗi, văn hóa được sử dụng để xác định cách thực hiện. Ví dụ, trong en-USvăn hóa thống trị, bạn có các biểu diễn chuỗi này:

  • 1.000.000,00 - một triệu với phân số hai chữ số
  • 1/29/2013 - ngày đăng bài này

Trong văn hóa của tôi ( da-DK) các giá trị có biểu diễn chuỗi này:

  • 1.000.000,00 - một triệu với phân số có hai chữ số
  • 29-01-2013 - ngày đăng bài này

Trong hệ điều hành Windows, người dùng thậm chí có thể tùy chỉnh cách định dạng số và ngày / lần và cũng có thể chọn văn hóa khác ngoài văn hóa của hệ điều hành. Các định dạng được sử dụng là sự lựa chọn của người dùng đó là cách nó nên được.

Vì vậy, khi bạn định dạng một giá trị được hiển thị cho người dùng sử dụng ví dụ ToStringhay String.Formathay phân tích cú pháp từ một chuỗi sử dụng DateTime.Parsehoặc Decimal.Parsemặc định là sử dụng CultureInfo.CurrentCulture. Điều này cho phép người dùng kiểm soát định dạng.

Tuy nhiên, rất nhiều định dạng và phân tích chuỗi thực sự không phải là các chuỗi trao đổi giữa ứng dụng và người dùng mà là giữa ứng dụng và một số định dạng dữ liệu (ví dụ: tệp XML hoặc CSV). Trong trường hợp đó, bạn không muốn sử dụng CultureInfo.CurrentCulturevì nếu định dạng và phân tích cú pháp được thực hiện với các nền văn hóa khác nhau thì nó có thể bị hỏng. Trong trường hợp đó bạn muốn sử dụng CultureInfo.InvariantCulture(dựa trên en-USvăn hóa). Điều này đảm bảo rằng các giá trị có thể làm tròn mà không gặp vấn đề gì.

Lý do mà ReSharper mang đến cho bạn những cảnh báo là một số nhà văn ứng dụng không nhận thức được sự khác biệt này có thể dẫn đến kết quả ngoài ý muốn nhưng họ không bao giờ khám phá ra điều này bởi vì họ CultureInfo.CurrentCultureen-UStrong đó có các hành vi tương tự như CultureInfo.InvariantCulture. Tuy nhiên, ngay khi ứng dụng được sử dụng trong một nền văn hóa khác, nơi có cơ hội sử dụng một nền văn hóa để định dạng và một nền văn hóa khác để phân tích ứng dụng có thể bị hỏng.

Vì vậy, để tổng hợp nó:

  • Sử dụng CultureInfo.CurrentCulture(mặc định) nếu bạn định dạng hoặc phân tích chuỗi người dùng.
  • Sử dụng CultureInfo.InvariantCulturenếu bạn đang định dạng hoặc phân tích một chuỗi cần được phân tích cú pháp bởi một phần mềm.
  • Hiếm khi sử dụng một nền văn hóa quốc gia cụ thể vì người dùng không thể kiểm soát cách định dạng và phân tích cú pháp được thực hiện.

1
Liên quan đến điểm cuối cùng, "Hiếm khi sử dụng một nền văn hóa quốc gia cụ thể ...", định dạng tiền tệ có phải là một ngoại lệ không? Ví dụ: nếu tôi có một Decimalbiến chứa một giá trị nhất định bằng Đô la Mỹ, tôi có muốn tạo một ngoại lệ và sử dụng en-USlàm văn hóa khi hiển thị nó để đảm bảo tôi không nhận được kết quả giống như một số bằng Euro không? Tôi đã thử CultureInfo.InvariantCulture , nhưng đã nhận được điều này cho điểm đánh dấu tiền tệ ¤, vì vậy tôi không chắc đó là cách đúng đắn.
Jeff B

1
@JeffBridgman: Lời khuyên của tôi chỉ là lời khuyên chung chung và có thể không áp dụng cho trường hợp cụ thể của bạn. Tuy nhiên, tôi nghĩ rằng cách bạn hiển thị dấu thập phân (dấu phẩy hoặc dấu chấm) phải là thứ mà người dùng kiểm soát (ví dụ: sử dụng CultureInfo.CurrentCulture). Nếu bạn ngoài việc hiển thị một số cần tiền tệ thì có lẽ bạn nên làm điều đó một cách nhất quán, tức là không sử dụng một CultureInfovà thay vào đó sử dụng mã ba loại tiền tệ như thế nào USD 1,234.56. Sau đó, bạn không gặp phải vấn đề ánh xạ tiền tệ đến văn hóa.
Martin Liversage

26

Theo Microsoft:

Thuộc tính CultureInfo.InvariantCARM không phải là một nền văn hóa trung lập hay cụ thể. Đó là một loại văn hóa thứ ba không nhạy cảm về văn hóa. Nó được liên kết với ngôn ngữ tiếng Anh nhưng không phải với một quốc gia hoặc khu vực.

(từ http://msdn.microsoft.com/en-us/l Library / 4c5zdc6a ( vs.71 ) .aspx )

Vì vậy, InvariantCARM là similair cho văn hóa "en-US" nhưng không hoàn toàn giống nhau. Nếu bạn viết:

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"

sau đó s1 và s2 sẽ có định dạng similair nhưng InvariantCARM thêm các số 0 hàng đầu và "en-US" sử dụng AM hoặc PM.

Vì vậy, InvariantCARM tốt hơn cho việc sử dụng nội bộ, khi bạn ví dụ lưu một ngày vào tệp văn bản hoặc phân tích dữ liệu. Và một CultureInfo được chỉ định sẽ tốt hơn khi bạn trình bày dữ liệu (ngày, tiền tệ ...) cho người dùng cuối.


3
Tôi đã chạy mã ví dụ của bạn để xác nhận: InvariantCARM sử dụng MM / dd / yyyy của Mỹ thay vì theo định dạng đầu tiên theo tiêu chuẩn ISO 8601. Mặc dù đó là dành cho lưu trữ di động và xử lý cơ học, chứ không phải cho tiêu dùng của con người. Thật khó hiểu
Max Barraclough

4

Đối với những thứ như số (dấu thập phân, dấu phẩy theo số lượng), chúng thường được ưa thích trong văn hóa cụ thể.

Một cách thích hợp để làm điều này sẽ được đặt ở cấp độ văn hóa (đối với tiếng Đức) như thế này:

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

4

JetBrains đưa ra một lời giải thích hợp lý ,

"Chuyển đổi cấu trúc dữ liệu đột xuất thành văn bản chủ yếu phụ thuộc vào văn hóa hiện tại và có thể dẫn đến kết quả ngoài ý muốn khi mã được thực thi trên máy có ngôn ngữ khác với nhà phát triển ban đầu. Để tránh sự mơ hồ, ReSharper cảnh báo bạn về bất kỳ trường hợp nào trong mã nơi xảy ra sự cố như vậy. "

nhưng nếu tôi đang làm việc trên một trang web mà tôi biết sẽ chỉ bằng tiếng Anh, tôi chỉ bỏ qua gợi ý.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.