ArgumentOutOfRangeException出现奇怪的本地化问题

时间:2013-04-27 00:32:29

标签: c# .net exception localization internationalization

对于安装了Windows版本并且使用英语作为唯一语言的人来说,这个“问题”可能很难测试/重现。我在安装了“丹麦语(丹麦语)”("da-DK"文化),.NET 4.5版的Windows 7计算机上执行此操作。

我遇到了以下令人惊讶的行为。代码:

Console.WriteLine("Now using intalled UI culture");
Thread.CurrentThread.CurrentUICulture = CultureInfo.InstalledUICulture;
Console.WriteLine(new ArgumentNullException().Message);
Console.WriteLine(new ArgumentOutOfRangeException().Message);

Console.WriteLine();

Console.WriteLine("Now using invariant culture");
Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture;
Console.WriteLine(new ArgumentNullException().Message);
Console.WriteLine(new ArgumentOutOfRangeException().Message);

产生以下输出:

Now using intalled UI culture
En værdi må ikke være null.
Det angivne argument lå uden for det gyldige værdiområde.

Now using invariant culture
Value cannot be null.
Det angivne argument lå uden for det gyldige værdiområde.

说明:在第一部分中,当UI线程为丹麦语时,我们会看到两个本地化的异常消息。但在第二部分中,我们看到一条英语(“不变”)消息和一条丹麦语消息,即使UI文化与丹麦文化无关。

我还尝试了很多其他mscorlib异常类,看起来只有System.ArgumentOutOfRangeException不尊重UI文化的变化。

为什么ArgumentOutOfRangeException与此方面的其他例外不同?

(如果其他人(其他版本的操作系统和框架和/或其他语言)看到相同的行为,那将会很有趣。)

PS!在同一台机器上将以下行粘贴到PowerShell(其目标是另一个.NET版本)会导致与<{1}}相反的问题?!

ArgumentOutOfRangeException

(保持长行以确保PowerShell在同一个线程上执行每行的两个语句。)

1 个答案:

答案 0 :(得分:2)

如果查看两个例外的源代码,您可以快速查看问题。这是ArgumentNullException

的构造函数
public ArgumentNullException() : 
           base(Environment.GetResourceString("ArgumentNull_Generic")) {
    base.SetErrorCode(-2147467261);
}

正如您所看到的,每次从ressources加载错误消息。虽然ArgumentOutOfRangeException的构造看起来像这样:

public ArgumentOutOfRangeException() : base(RangeMessage) {
    base.SetErrorCode(-2146233086);
}

其中RangeMessage是私有静态属性:

private static string RangeMessage {
    get {
        if(_rangeMessage == null) {
            _rangeMessage = Environment.GetResourceString(
                                        "Arg_ArgumentOutOfRangeException");
        }
        return _rangeMessage;
    }
}

您可以在此处看到缓存错误消息的问题。所以它不会更新。我看到的唯一方法是使用反射访问private static volatile string _rangeMessage;并将其重新设置为null