我正在使用一個 .Net Core 6 庫 (dll),其中,除其他功能外,數字和日期/時間資訊以字串形式輸出,并且此代碼需要全球化,即。要有文化意識。圖書館是一個檔案制作系統,所以在同一個應用程式會話中,用戶會為 de-CH、de-FR、en-US 等制作檔案。所以基本上,我們希望圖書館有文化意識,但是輸出的文化應該有它的“標準”格式,而不是在作業系統級別或用戶級別自定義的格式。
例如對于十進制值,庫代碼使用這些方法來輸出內容:
public string ToString();
public string ToString(string? format);
public string ToString(IFormatProvider? provider)
public string ToString(string? format, IFormatProvider? provider)
因此,在具有不同文化設定的不同計算機上的不同用戶呼叫這些多載時,輸出的格式將有所不同:小數點分隔符可以是逗號或點,千位分組分隔符可能是非制動空格或 ' 等。
但是,當provider通過使用特定文化的實體(例如“fr-CH”(瑞士-法語)和 CultureInfo.UseUserOverride == false 顯式傳遞引數時,我期望始終相同的輸出字串,獨立于用戶和/或電腦。所以,我在想,.Net 將為所有文化型別的 CultureInfo 實體的所有屬性提供“內置”值,并且通過引數useUserOverride: false我可以強制格式化使用這些“內置”值,因此會輸出總是相同的字串。
但事實似乎并非如此!
代碼:
CultureInfo cultInfo = new CultureInfo(name: "fr-CH", useUserOverride: false) //* fr-CH" is Swiss-French
Decimal myDec = -123456789123456.987654321M;
String output = myDec.ToString(format: "N4", provider: cultInfo); // I was expecting always same output independent, which user is calling it in which computer, but this is not the case!
此示例代碼是使用 .Net Core 6 作為控制臺應用程式編譯的,我在 a) Windows 10 Pro PC 和 b) 在 Windows Server 2012R2 上運行它,它們具有不同的輸出。
- Fr-CH/Windows Pro 10 PC:-123 456 789 123 456,9877
- Fr-CH/Windows Server 2012R2:-123'456'789'123'456.9877
設定相同CultureInfo cultInfo = CultureInfo.InvariantCulture:然后結果看起來總是相同的,這是預期的。
我還嘗試設定Thread.CurrentThread.CurrentCulture和Thread.CurrentThread.CurrentUICulture使用cultInfo上面的-variable 然后呼叫ToString(format?, provider?),但沒有效果:結果與沒有設定CurrentThread. 附注。我實際上從這里、這里和這里了解到,設定Thread.CurrentThread.CurrentUICulture與格式無關(我的情況),但與翻譯(resx 的東西)無關。
我知道有關CultureInfo-class 的大量 Microsoft 檔案,但我看不到那里森林中的樹。
我的問題如下:
- 是否有任何版本的 .Net Core(或任何版本的 .Net Framework)對所有 CultureInfo 屬性都有“內置值”?
- 我如何才能強制我的代碼始終完全使用獨立于環境的給定文化的文化?
這對于能夠以可靠的方式對庫輸出進行單元測驗非常重要。
這可能很重要,當回讀(使用 System.Convert(value, provider?) 任何用戶在任何計算機上輸出的值時(只知道他們輸出的文化)。
uj5u.com熱心網友回復:
您可以設定自定義文化并根據需要配置該文化。
從現有的中性開始,例如InvariantCulture.
制作一個克隆以保持InvariantCulture原樣。
var clone = CultureInfo.InvariantCulture.Clone() as CultureInfo;
然后對該克隆進行所需的更改 - 例如:
clone.NumberFormat.NumberDecimalSeparator = ",";
clone.NumberFormat.NumberGroupSeparator = ".";
可選但建議,您可能想要制作它的只讀版本。
var customCulture = CultureInfo.ReadOnly(clone);
在需要固定控制輸出的任何地方使用該文化 - 例如:
var number = -123456789123456.987654321M;
var formattedNumber = number.ToString("N4", customCulture)); // -123.456.789.123.456,9877
在將格式化string版本決議回 a時應用相同的文化decimal- 例如:
var parsedNumber = decimal.Parse(formattedNumber, customCulture);
如果您對如何CultureInfo設定a 感興趣,請查看源代碼。
簡而言之,InvariantCulture一種具有固定設定,而另一種則依賴于作業系統和可選的用戶覆寫。
從檔案:
.NET 從多種來源之一中獲取其文化資料,具體取決于實作、平臺和版本:
在 .NET Framework 3.5 和更早版本中,文化資料由 Windows 作業系統和 .NET Framework 提供。
在 .NET Framework 4 及更高版本中,文化資料由 Windows 作業系統提供。
在 Windows 上運行的所有 .NET Core 版本中,文化資料由 Windows 作業系統提供。
因此,在特定 .NET 實作、平臺或版本上可用的文化可能在不同的 .NET 實作、平臺或版本上不可用。
某些 CultureInfo 物件因底層平臺而異。
uj5u.com熱心網友回復:
將它設定在標題上以使其作業,如果您不希望它在每個地方重復:
CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo("fr-CH");
.....
Decimal myDec = -123456789123456.987654321M;
String output = myDec.ToString(format: "N4");
Console.WriteLine(output);
當您在其他計算機上運行代碼時,請嘗試檢查cultureinfo 并查看它會回傳什么。我敢打賭它沒有將它設定為 fr-CH:
CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture;
Console.WriteLine(currentCulture.Name);
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/392002.html
