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 スレッドがデンマーク語の場合に予想される 2 つのローカライズされた例外メッセージが表示されます。しかし、2 番目のセクションでは、UI カルチャがデンマーク語とは関係がなくなったとしても、1 つの英語 (「不変」) メッセージと 1 つのデンマーク語メッセージが表示されます。

mscorlib他の多くの例外クラスでもこれを試しましたがSystem.ArgumentOutOfRangeException、UI カルチャの変更を尊重していないようです。

ArgumentOutOfRangeExceptionこの点で他の例外と異なるのはなぜですか?

(他の人 (OS とフレームワークの他のバージョン、および/または他の言語) で同じ動作が見られるかどうかを聞くのは興味深いことです。)

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 に答える