2

对于以英语作为唯一语言安装 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 版本为目标)中会产生相反的问题ArgumentOutOfRangeException?!

[Threading.Thread]::CurrentThread.CurrentUICulture = [Globalization.CultureInfo]::InstalledUICulture; New-Object ArgumentNullException;
[Threading.Thread]::CurrentThread.CurrentUICulture = [Globalization.CultureInfo]::InstalledUICulture; New-Object ArgumentOutOfRangeException;
[Threading.Thread]::CurrentThread.CurrentUICulture = [Globalization.CultureInfo]::InvariantCulture; New-Object ArgumentNullException;
[Threading.Thread]::CurrentThread.CurrentUICulture = [Globalization.CultureInfo]::InvariantCulture; New-Object ArgumentOutOfRangeException;

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

4

1 回答 1

2

如果您查看这两个异常的源代码,您可以快速发现问题。这是 的构造函数ArgumentNullException

public ArgumentNullException() : 
           base(Environment.GetResourceString("ArgumentNull_Generic")) {
    base.SetErrorCode(-2147467261);
}

如您所见,每次从资源中加载错误消息。虽然构造函数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.

于 2013-04-27T10:37:42.193 回答