2009-09-28 31 views
13

Tôi muốn đảm bảo rằng các số nhất định trong ứng dụng của mình được in mà không có bất kỳ dấu tách, nhóm, v.v. bất kể môi trường hiện tại là gì. Có vẻ như hai phương pháp sau đây cho ra kết quả tương tự (có thể có nhiều hơn):ToString ("0") so với ToString (CultureInfo.InvariantCulture)

123456789.ToString("0"); 
123456789.ToString(CultureInfo.InvariantCulture); 

Bạn có biết bất kỳ trường hợp hoặc quirks nào không? Cái nào là "đúng" hơn? Bạn sẽ sử dụng cái nào?

Tôi đã từng sử dụng thẻ thứ hai, nhưng gần đây tôi đã tìm thấy thiết bị đầu tiên và bắt đầu sử dụng vì nó không yêu cầu thêm using System.Globalization.

Trả lời

0

Nếu bạn đang muốn đảm bảo để xác định "không có định dạng, không có vấn đề gì" Cá nhân tôi nghĩ là lựa chọn đầu tiên bạn có:

123456789.ToString("0"); 

tốt hơn truyền đạt ý định. Nhược điểm sẽ là nếu một nền văn hóa overrode chuỗi định dạng của "0" cho loại số bạn đang sử dụng.

+0

Ồ, tôi đã bây giờ biết rằng bạn có thể ghi đè lên các dây định dạng? Tôi cần tra cứu nó. –

+0

Bạn có chắc chắn về quá tải không? MSDN (http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx) nói: "Bất kỳ ký tự đơn nào khác [so với một trong các tiêu chuẩn đó] sẽ ném ra một định dạng FormatException tại thời gian chạy." –

+0

Tôi không chắc đây có phải là trường hợp hay không. Tôi thấy một chuyến đi nhanh đến thư viện MSDN sẽ cho tôi thấy :). –

2

Như tôi thấy, Định dạng đầu tiên sẽ là một số có ít nhất một ký tự sử dụng văn bản mặc định của máy tính. Thứ hai sẽ định dạng nó như là một số tùy thuộc vào các quy tắc bất biến.

Bobby

+0

Sửa lỗi nếu tôi sai: Tôi nghĩ rằng không có nhóm chữ số, dấu phân tách, vv .. áp dụng cho 123456789.ToString ("0")? –

+0

Uhhh ... nó thực sự không. Tôi đã nhầm nó cho một biểu tượng định dạng như "N0", mà không áp dụng các quy tắc văn hóa hiện tại. Bạn nói đúng, vì 0 là định dạng trực tiếp nên nó không áp dụng thông tin văn hóa _any_. Mặc dù, ai đó cũng có thể sử dụng 123456789.ToString(); . – Bobby

5

Hai phương pháp này không tương đương: là người đầu tiên được sử dụng CurrentCulture. Điều này có thể dẫn đến dấu chấm/dấu phẩy thêm trong các nền văn hóa nhất định (tôi không có ví dụ).

Khi bạn sử dụng InvariantCulture bạn chắc chắn luôn sử dụng cùng một định dạng.

Chỉnh sửa: Và, nếu bạn sử dụng CodeAnalysis, điều đó sẽ khiếu nại khi bạn không sử dụng CultureInfo.

+0

Tôi đã thử nghiệm cái đầu tiên bằng cách sửa đổi văn bản chuỗi hiện tại, và nó không ảnh hưởng đến nó. Tôi nghĩ rằng "0" có nghĩa là: ít nhất một chữ số + không có chữ số nhóm hoặc phân cách. Nếu tôi muốn có một số nhóm hoặc phân cách chữ số, tôi nghĩ rằng tôi sẽ phải làm một cái gì đó như "000.000". –

+2

Nhưng bạn đúng: InvariantCulture "âm thanh" rõ ràng hơn. Ngay cả MSDN nói "... nó được liên kết với ngôn ngữ tiếng Anh nhưng không phải với bất kỳ quốc gia/khu vực". Hmm, khi tôi nghĩ về nhiều hơn, ToString (CultureInfo.InvariantCulture), nó có nghĩa là số nếu định dạng bằng cách sử dụng "G". Tất cả chỉ xảy ra để làm việc CHỈ vì "G" dường như không sử dụng bất kỳ nhóm nào. NHƯNG (Tôi chỉ nhìn nó lên) văn hóa bất biến có một số nhóm được chỉ định. Ví dụ, hãy thử 12345789.ToString ("N", CultureInfo.InvariantCulture). –

17

Dựa trên câu trả lời và thảo luận ở đây, tôi đã thực hiện một số điều tra thêm. Dưới đây là những gì tôi tìm thấy:

  • Khi bạn sử dụng 12345678.ToString() mà không cần bất kỳ đối số, NET sử dụng chung các chung format specifier "G" mà chỉ bị ảnh hưởng bởi NumberFormatInfo.NegativeSign, NumberFormatInfo. NumberDecimalSeparator, NumberFormatInfo.NumberDecimalDigits và NumberFormatInfo.PositiveSign. Với tôi điều này nói rằng trong bất kỳ nền văn hóa 12345678.ToString() nên luôn luôn sản xuất "12345678".

  • Nếu bạn muốn chữ số riêng biệt, bạn cần phải sử dụng các định dạng số specifier "N" (hoặc, tất nhiên, để cung cấp một chuỗi định dạng tùy chỉnh). Nhóm chữ số cũng áp dụng cho "C" và "P".

  • Các văn hóa bất biến không thực sự xác định chữ số nhóm (bằng 3 chữ số, tất nhiên) và thiết bị tách chữ số. Vì vậy, lý do mà 123456789.ToString(CultureInfo.InvariantCulture) tạo ra "123456789" không phải vì văn hóa bất biến, mà là do định dạng số chung mặc định là "G".

Vì vậy, tôi sẽ nói rằng kết luận là nó hoàn toàn OK không phải lo lắng về bất kỳ đối số phụ và chỉ sử dụng:

12345678.ToString() 

Tôi nghĩ rằng đây là tốt nhất từ ​​tất cả các trường hợp bởi vì nó có nghĩa là thông thường bạn không cần phải gọi ngay cả ToString() vì hầu hết các chức năng in/ghi đều chấp nhận tất cả các loại đối số và làm ToString() cho bạn.

1

2 dòng làm những việc khác nhau. Dòng đầu tiên định dạng số với văn hóa địa phương và thứ hai chuyển đổi nó thành chuỗi mà không cần định dạng nhưng sử dụng CultureInfo.InvariantCulture.

Bạn sử dụng CultureInfo.InvariantCulture với loại phương thức này (ToString, ToLower ...) để đảm bảo rằng khi giá trị được sử dụng bởi bất kỳ phần mềm nào (cơ sở dữ liệu, thư viện khác ...), bất kể văn hóa của chúng là gì , nó sẽ mang lại giá trị như nhau và khi họ có thể nhận giá trị này, họ có thể tiếp tục xử lý nó. Tuy nhiên nếu bạn không sử dụng phần mềm này thì phần mềm của bạn phải tìm hiểu văn hóa của bạn là gì. Ý của bạn là dấu phân tách thập phân với dấu phẩy hay cái gì khác ...?

Tất cả và sử dụng CultureInfo.InvariantCulture khi bạn muốn trao đổi/sử dụng giá trị giữa các thư viện, cơ sở dữ liệu và sử dụng CultureInfo.CurrentCulture để hiển thị cho người dùng ứng dụng của bạn.

// for softwares 
string mystring1 = 1234.ToString("0", CultureInfo.InvariantCulture); 

// for your application users 
string mystring2 = 1234.ToString("0", CultureInfo.CurrentCulture); 
1

(~ 5 năm sau ...)

Tôi đã nhìn lên câu hỏi này chính xác, nhưng vì không có câu trả lời được chấp nhận và mặc dù Jan Zich là đúng Tôi nghĩ tôi sẽ đặt lại với nhau một chút ví dụ để kiểm tra điều này.

Tôi cũng sẽ đi xa để nói rằng không có sự khác biệt giữa .ToString(), .ToString ("0") và .ToString (Bất kỳ thông tin văn hóa nào) (theo số nguyên và số thập phân có liên quan)

var cultures = CultureInfo.GetCultures(CultureTypes.AllCultures) 
    .Except(CultureInfo.GetCultures(CultureTypes.SpecificCultures)); 

foreach(var c in cultures){ 
    var num = (int.MinValue);/* 
    var num = (int.MaxValue);/* 
    var num = (decimal.MinValue);/* 
    var num = (decimal.MaxValue);/* 
--*/ 

    var s1 = num.ToString("0") ; 
    var s2 = num.ToString(c); 
    if(s1 != s2){ 
     var s = string.Format("{2}: {0} {1}",s1,s2,c); 
     s.Dump(); 
    } 
} 

LinqPad snippet

0

các ToString()ToString (CultureInfo.InvariantCulture) luôn cung cấp cho các kết quả tương tự cho các số nguyên.

Đoạn code dưới đây mang đến cho "809 nền văn hóa kiểm tra, 0 khác biệt tìm thấy" Kết quả trên máy tính của tôi:

var cultures = CultureInfo.GetCultures(CultureTypes.AllCultures).ToArray(); 
var numbers = new[] { 0, -1, 1, int.MinValue, int.MaxValue }; 

var diffsFound = 0; 
foreach (var culture in cultures) 
{ 
    foreach (var number in numbers) 
    { 
     var s1 = number.ToString(); 
     var s2 = number.ToString(culture); 
     if (s1 != s2) 
     { 
      Console.WriteLine($"{culture.DisplayName}: {s1} != {s2}"); 
      diffsFound++; 
     } 
    } 
} 

Console.WriteLine($"{cultures.Length} cultures tested, {diffsFound} differences found."); 
Các vấn đề liên quan