7

私のアプリケーションで「利用可能な言語」のリストを提示したいという状況があります (ちなみに、それがオッズを作る場合、これは ASP .NET MVC 3 アプリケーションです)。ビルドに含まれているのはresxファイルだけであるため、このリストを何らかの方法で自動的に取得できると思いました(英語の英国、ドイツ語のオーストリアなどをサポートする必要はありません。英語またはドイツ語のみです)。以下に提示するスキーム(少し集中的なアプローチであるため、シングルトンとして実装されています)。

問題は、一部のマシンではそのようなリソースがなくても「アラビア語」を返し、私のマシンでは (VS 2012 をインストールしたため) すべてを返すことです (これは、2 つの実際のカルチャとアラビア語だけを返すよりも理にかなっていますしかし、ResourceManager はこの情報を取得できるように設計されていないように見えるので、おそらく文句を言うべきではありません)。これがスキームです...

(私は Strings.resx と Strings.de.resx ファイルを持っています)

IEnumerable<CultureInfo> cultures =
    CultureInfo.GetCultures(CultureTypes.NeutralCultures)
        .Where(c =>
                   {
                       // Exclude the invariant culture and then load up
                       // an arbitrary string so the resource manager
                       // loads a resource set, then get the set for the
                       // current culture specifically and it is, sometimes
                       // (I thought always but I was wrong) null if no
                       // set exists
                       if (c.LCID == CultureInfo.InvariantCulture.LCID)
                           return false;

                       var rm = Strings.ResourceManager;
                       rm.GetString("HELLO", c);
                       return rm.GetResourceSet(c, false, false) != null;
                   });

それで、言語固有のディレクトリが次のように存在するかどうかに基づいて、これを行うことができると思いました。

var neutralCulture = new[]
{
    CultureInfo
        .CreateSpecificCulture(((NeutralResourcesLanguageAttribute)
                                Assembly
                                    .GetExecutingAssembly()
                                    .GetCustomAttributes(
                                        typeof (NeutralResourcesLanguageAttribute),
                                        false)[0])
                                .CultureName)
};

IEnumerable<CultureInfo> cultures =
    CultureInfo.GetCultures(CultureTypes.NeutralCultures)
        .Where(c => Directory.Exists(c.TwoLetterISOLanguageName))
        .Union(neutralCulture);

これは「機能します」(英語とドイツ語を返す限り)が、誰かがフォルダーを作成してすべてを台無しにするなどのランダムな問題が発生しやすいため、非常に安定したアプローチではないと思います。おそらく、いくつかのより賢明なチェックでこれらの問題を軽減できますが(where句はより洗練されたものを求めています)、ここで質問があります(最終的に)...

今のところ、設定ファイルを使用して完全にシンプルに保つことを考えていますが、これを行うより良い方法はありますか (または、安全な方法で自動的に行うことができますか) ?

4

2 に答える 2

2

自動検出のための 2 番目のアプローチが気に入っています。ただし、これは (アプリケーションの開始時または静的コンストラクターの一部として) 1 回だけ実行し、サポートされているカルチャ情報を要求するたびに計算するのではなく、静的にする必要があることを付け加えておきます。

実際には自動ではありませんが、構成アプローチも同様に機能すると思います。その場合の私の唯一の考えは、言語をローカライズしている場合、それはレーダーの下でアプリケーションに忍び込むものではないということです. そうは言っても、その時点で構成値を追加するのは簡単なことのように思えます (または忘れがちです)。

メソッド呼び出しでこの情報を提供するために .NET Framework に組み込まれているものを私は知りません。

于 2012-08-20T11:37:14.813 に答える
1

これを行う有効で信頼できる方法が見つかりませんでした。

各アセンブリで、サポートされているカルチャを参照する次のようなコードを記述します。私たちにできることはそれだけです。ローカリゼーションを追加するときは、この配列を忘れずに更新する必要があります。

internal static class ThisAssembly
{
    static readonly string[] SupportedCultures = new string[] { "en-US", "de-DE", };
}

私もしようとしました:

  • ロードされた衛星アセンブリを列挙します。そのための方法はありません。
  • の値を取得ResourceManager._resourceSets: ロードされたセットのディクショナリは、正しい値と無効な値を提供します。

しかし、役に立たない。

于 2016-01-10T12:11:07.253 に答える