web-dev-qa-db-ja.com

戻り値の型を持つtry-catchブロック

次のような何かを返すメソッドがある場合

public DataTable ReturnSomething()
{
   try
   {  
      //logic here
     return ds.Tables[0];
   }
   catch (Exception e)
   {
      ErrorString=e.Message;
   }
}

これにより、コンパイラエラーが発生します。これは、明らかにcatch{}ブロックは何も返しません。

したがって、戻り値を持つメソッドがある場合、try-catchブロックを使用しません。これは悪い習慣です。エラーが発生した場合は、エラー文字列をそのエラーに設定したいと思います。しかし、それなら私も戻り値が必要です。助言?

13
Julia

次のような一時変数に戻り値を格納します。

public DataTable ReturnSomething()
{
    DataTable returnValue = null;

    try
    {
        //logic here
        returnValue = ds.Tables[0]; 
    }
    catch (Exception e)
    {
        ErrorString=e.Message;
    }

    return returnValue;
}
33
Simon

Catchブロックで例外を発生/スローし、呼び出しメソッドで処理する必要があります。

public void invokeFaultyCode()
{
    try
    {
        DataTable dt = ReturnSomething();
    }
    catch(Exception e)
    {
        // Print the error message, cleanup, whatever
    }    
}
public DataTable ReturnSomething() throws Exception
{
   try
   {  
      //logic here
     return ds.Tables[0];
   }
   catch (Exception e)
   {
      ErrorString=e.Message;
      throw;
   }
}

PS:構文エラーが発生して申し訳ありません。C#では少し錆びています。

17
Manrico Corazzi

呼び出し元をtrycatchでラップする必要があります...呼び出されたルーチンで発生した例外はすべて呼び出し元にバブルアウトし、そこでキャッチできます。

個人的には、呼び出し元に例外を処理させる必要があるため、このルーチンでtrycatchを実行するのはやり過ぎだと思います。

私の例では、これは次のようにコーディングされます...

private void DoSomething() {
    try {
        DataTable dt = ReturnSomething();
    }
    catch (Exception ex) {
    }    
}

public DataTable ReturnSomething() {
    DataTable dt = new DataTable();

    // logic here
    return dt;
}
7
Bryan Sebastian

ErrorString変数は、疑わしいことにエラーコード変数のように見えます。推奨される方法は、エラーコードに格納するのではなく、必要に応じて例外を使用してエラー情報を直接渡すことです。

ErrorStringを使用すると、呼び出し元が例外をキャッチするだけの場合と同じことを効果的に実行できます。つまり、メソッド自体からエラーに応答する責任を取り除くことができます。これは良い目標です。ただし、エラー文字列を使用しても、例外を使用しても何も得られません。実際、この方法で情報が失われます。発生する可能性のあるエラーにはいくつもの種類があり、その多くには、障害に関するコンテキスト情報を保持するための独自の特別なプロパティを備えた特別な例外が関連付けられています。メッセージを文字列に格納するだけで、この情報は失われます。

したがって、呼び出し元から発生しているエラーの種類を隠すことが特に目的でない限り、例外を通過させることによってのみ得ることができます。

考慮すべきもう1つのことは、これが本当にエラーシナリオであるかどうかです。そうである場合、呼び出し元のメソッドが戻り値を気にする可能性はほとんどありません。その場合、例外を解除して何も返さないだけで、心配する必要はありません。それが実際にはエラーシナリオではなく、発信者が続行して何か他のことをする場合は、それは発信者が決定することですよね?エラー文字列とダミーのDataTableまたはnullを返すことで、すべてのコンテキスト障害情報を含む例外をスローするよりも、まだ多くのメリットはありません。

6
Chris Ammerman

「例外ルートをスローしない」(私は必ずしも推奨しているわけではありません)に向かう場合は、MSが使用するTryParseアプローチに従うことができます。

何かのようなもの:

private string FillDataTable(out DataTable results)
{

  try
{
  results = new DataTable(); //something like this;
  return String.Empty;
}
catch (Exception ex)
{
  results = null;
 return ex.Message;

}

}

4
kemiller2002

それはあなたのアプリケーションに依存します。 null、空のDataTable、または状況に応じて適切なものを返すことができます。

3
Anton Gogolev

それでもメッセージを設定して、nullまたはc#に相当するものを返すことができると思います

public DataTable ReturnSomething(){ 
   try {
        //logic here 
        return ds.Tables[0]; 
   } catch (Exception e) {
        ErrorString=e.Message;
        return null;
   }
}
3
zaczap

これはどう :

public DataTable ReturnSomething(out string errorString)
{
   errorString = string.Empty;
   DataTable dt = new DataTable();
   try
   {  
      //logic here
     dt = ds.Tables[0];
   }
   catch (Exception e)
   {
      errorString = e.Message;
   }
   return dt;
}
2
Canavar

あなたの例では例外をキャッチしている(そしてそれを再びスローしない)ので、外部コードはすべてが大丈夫であると想定しているので、何か役に立つものを返す必要があります。

そこで例外をキャッチして問題のないことを行う必要があるが、それでもエラーの場合は、それをスローするか、別の例外をスローする必要があります。おそらく、InnerExceptionとしてキャッチしたものを使用します。

1
Kris

あなたのコードは十分に高いレベルの呼び出しスタックで実行されており、UIコードとブレンドされていると思います。これが実際に当てはまる場合は、return nullキャッチブロック内。ただし、再利用可能なコードを記述している場合は、UI操作が含まれないようにリファクタリングし、呼び出しスタックの上位レベルで例外を処理する必要があります。

0
Mehrdad Afshari

以下のサンプルコードのように行うことができます。

public DataTable ReturnSomething(out string OutputDesc)
{
   try
      {
         //logic here
         OutputDesc = string.Format("Your Successful Message Here...");
         return ds.Tables[0];
      }
      catch (Exception e)
      {
         OutputDesc =e.Message;
         return null;
      }

}
0
king zecole