4

tryC#でインラインステートメントを呼び出すことは可能ですか?

私は自分のウェブサイトの言語を検出していますが、言語がen-GR何らかの理由でクライアント側のようなものである場合、.NET が例外をスローすることがあります。だから私は実際に何かを捕まえていなくても、tryそしてまた使用する必要があります。catch

この状況では、完全にやり過ぎのように思えます。

// Set allowed languages
string[] allowedLanguages = { "en", "fr", "ru" };

// Get all possible values
var routeLanguage = (filterContext.RouteData.Values["lang"] != null && allowedLanguages.Contains(filterContext.RouteData.Values["lang"].ToString())) ? filterContext.RouteData.Values["lang"].ToString() : null;
var cookieLanguage = (filterContext.HttpContext.Request.Cookies["lang"] != null && allowedLanguages.Contains(filterContext.HttpContext.Request.Cookies["lang"].Value)) ? filterContext.HttpContext.Request.Cookies["lang"].Value : null;
string clientLanguage = null;
try
{
    clientLanguage = (filterContext.HttpContext.Request.UserLanguages != null) ? new CultureInfo(filterContext.HttpContext.Request.UserLanguages[0]).TwoLetterISOLanguageName : null; // Exception sometimes without `try`
}
catch (Exception)
{
}

編集

ユーザーが自分のカルチャ情報に何を持っているかを制御できないため、例外は修正できるものではありません。.NET は、en-FR を無効なものと見なします。

4

8 に答える 8

15

まず、最初に例外を回避する方法を理解することをお勧めします。まずはそこに集中してください。その例外がスローされるのには何らかの理由があり、それが何であるかを判断できる場合は、それを行わないでください。

実際にあなたの質問に答えるには: すぐに使える「この式のすべての例外を食べる」メカニズムはありませんが、独自のメカニズムを構築するのは簡単です:

static T EatExceptions(Func<T> func)
{
  try { return func(); } catch { }
  return default(T);
}
...
clientLanguage = (filterContext.HttpContext.Request.UserLanguages != null) ? 
  EatExceptions(() => new CultureInfo(filterContext.HttpContext.Request.UserLanguages[0]).TwoLetterISOLanguageName) :
  null; }

誰かが私がレビューしていたコードでそのような悪ふざけを引っ張ろうとした場合、私は... まあ、変更がチェックインされないだろうと言いましょう。このような例外を食べることは、99% の確率で非常に悪い考えです. 繰り返しますが、何が間違っているのかを理解し、それをやめてください。何か間違ったことをしないで、失敗を処理してください。

于 2013-02-09T16:34:11.703 に答える
7

try/catchステートメントを完全に削除しようとしましたか?

string clientLanguage = null;
var userLanguages = filterContext.HttpContext.Request.UserLanguages;
if (userLanguages != null && userLanguages.Length > 0)
{
    var culture = CultureInfo
        .GetCultures(CultureTypes.AllCultures)
        .FirstOrDefault(
            x => string.Equals(
                x.Name, 
                userLanguages[0].Name, 
                StringComparison.OrdinalIgnoreCase
            )
        );
    if (culture != null)
    {
        clientLanguage = culture.TwoLetterISOLanguageName;
    }
}

制御できない例外を処理する場合にのみ、try/catch を使用してください。その名前が示すように、例外は例外的なケースを処理するために使用する必要があります。

この場合、標準的な構文解析を行っているため、試行、スロー、キャッチなどではなく、防御的なプログラミングを行う方がはるかに優れています...

于 2013-02-09T16:30:23.417 に答える
1

あなたがしたことは、それを行う正しい方法です。あなたは、例外を取り除くことができない理由を述べました(そして、私はこれが事実だと思います)。だからあなたはそれを処理しなければなりません。残念ながら、C# には式としての try-catch がありません (それがどのように機能するかはわかりません。catch の「句」は値を返す必要があります)。

Func<T>または、 を受け取り、それを呼び出して値を呼び出し元に渡す小さなヘルパー関数を作成することもできます。例外が発生すると、(たとえば) が返されますdefault(T)。これにより、多くの混乱が解消され、再利用可能になります。

于 2013-02-09T16:34:01.010 に答える
1

まず、例外を回避してください。文字列が制御できないソースから来ているからといって、それを検証できないわけではありません。

回避できない場合は、予想される特定の例外をキャッチし、そのロジックをメソッドにカプセル化する必要があります。すべての例外をキャッチしないでください。

例えば:

public static CultureInfo TryGetCultureByName(string name)
{
   try
   {
     return new CultureInfo(name);
   }
   catch(CultureNotFoundException)//Only catching CultureNotFoundException
   {
     return null;
   }
}

そうすれば、後でこの特定のエラーを処理するためのより良い方法を見つけた場合に、簡単に置き換えることができます。

たとえば、 を作成しDictionary<string, CultureInfo>、そこから入力して、例外をスローすることなくカルチャを検索するためにCultureInfo.GetCultures()使用できます。TryGetValue

于 2013-02-09T16:39:08.740 に答える
0

さて、事前チェックについての (良い) アドバイスはさておき、これを行うにはいくつかの平凡/平凡/明白な方法があります。

まず、関数でラップできます。これはあなたにとって十分に一般的ではないと思います。

catchまたは、ブランチを折りたたむこともできます。

try
{
    clientLanguage = (filterContext.HttpContext.Request.UserLanguages != null) ? new CultureInfo(filterContext.HttpContext.Request.UserLanguages[0]).TwoLetterISOLanguageName : null; // Exception sometimes without `try`
} catch (Exception) { }

または、全体を 1 行に折りたたむこともできます。

try { clientLanguage = (filterContext.HttpContext.Request.UserLanguages != null) ? new CultureInfo(filterContext.HttpContext.Request.UserLanguages[0]).TwoLetterISOLanguageName : null; } catch (Exception) { }

エレガントではありませんが、シンプルで機能します。

于 2013-02-09T16:34:14.673 に答える