web-dev-qa-db-ja.com

C#でJavaスタイルのthrowsキーワードを使用する方法は?

Javaでは、 throws キーワードを使用すると、メソッドは独自に例外を処理せず、呼び出し元のメソッドに例外をスローすることを宣言できます。

C#に同様のキーワード/属性はありますか?

同等の機能がない場合、どのようにして同じ(または同様の)効果を達成できますか?

79
Louis Rhys

Javaでは、throwsキーワードを使用して、例外を処理するか、メソッドをスローする可能性のあるメソッドとしてマークする必要があります。

C#にはこのキーワードまたは同等のキーワードはありません。C#のように、例外を処理しない場合、キャッチされるまでバブルアップし、キャッチされない場合はプログラムを終了します。

それを処理したい場合は、次のことを再スローできます:

try
{
  // code that throws an exception
}
catch(ArgumentNullException ex)
{
  // code that handles the exception
  throw;
}
66
Oded

Opは、JavaのC#と同等の throws-throwキーワードではなく、を求めています。これは、Javaのメソッドシグネチャで使用され、チェック済み例外をスローできることを示します。

C#には、Javaチェック例外に直接相当するものはありません。C#には同等のメソッドシグネチャ句がありません。

// Java - need to have throws clause if IOException not handled
public void readFile() throws Java.io.IOException {
  ...not explicitly handling Java.io.IOException...
}

に変換する

// C# - no equivalent of throws clause exceptions are unchecked
public void ReadFile() 
{
  ...not explicitly handling System.IO.IOException...
}
93
serg10

はい、これは古いスレッドですが、答えをググリングしているときに頻繁に古いスレッドを見つけるので、見つけた便利なものを追加すると思いました。

Visual Studio 2012を使用している場合は、IDEレベルの「スロー」に相当するものを許可するために使用できる組み込みツールがあります。

上記のように XMLドキュメントコメント を使用する場合、 <exception> タグを使用して、メソッドまたはクラスによってスローされる例外のタイプと情報を指定できます。いつ、またはなぜスローされるかについて。

例:

    /// <summary>This method throws an exception.</summary>
    /// <param name="myPath">A path to a directory that will be zipped.</param>
    /// <exception cref="IOException">This exception is thrown if the archive already exists</exception>
    public void FooThrowsAnException (string myPath)
    {
        // This will throw an IO exception
        ZipFile.CreateFromDirectory(myPath);
    }
24
mvanella

bytes.com で資金を提供している同様の質問に対する回答を次に示します。

簡単な答えはノーです。C#にはチェック済みの例外はありません。言語の設計者は、このインタビューでこの決定について議論します。

http://www.artima.com/intv/handcuffs.html

最も近い方法は、XMLドキュメントでタグを使用し、NDocで生成されたドキュメントをコード/アセンブリと共に配布して、他の人がスローする例外を確認できるようにすることです(MSDNのドキュメントでMSが行っていることです)。ただし、Javaで慣れているように、コンパイラに依存して未処理の例外を通知することはできません。

18
Andreas_D

ここでほとんどの答えを読んだ後、いくつかの考えを追加したいと思います。

  1. XMLドキュメントのコメントに依存し、他の人が依存することを期待することは、適切な選択ではありません。私が遭遇したほとんどのC#コードは、XMLドキュメンテーションコメントでメソッドを完全かつ一貫して文書化していません。そして、C#でチェック例外がない場合、APIユーザーがそれらをすべて個別に処理する方法を知るためにメソッドがスローするすべての例外をどのように文書化できるかという大きな問題がありますか?覚えておいてください、あなたはあなたの実装でthrowキーワードを使って自分自身を投げたものについてのみ知っています。メソッド実装内で使用しているAPIは、ドキュメント化されていない可能性があり、実装でそれらを処理していないため、知らない例外をスローする可能性があるため、呼び出し元に直面して爆発します方法。言い換えれば、これらのXMLドキュメンテーションコメントは、チェックされた例外に置き換わるものではありません。

  2. アンドレアスは、C#設計チームがチェック例外を決定した理由についての回答で、アンダース・ヘイルスバーグとのインタビューをリンクしました。元の質問に対する最終的な回答は、そのインタビューに隠されています。

プログラマーは、最終的にどこでもtryを記述することでコードを保護します。したがって、例外が発生しても正しくバックアウトしますが、実際には例外の処理には興味がありません。

言い換えれば、特定のAPIに対してどのような例外が予想されるかについては、誰もが興味を持っているべきではありません。特定の例外を本当に気にしたい場合、それらを処理する方法はあなた次第であり、誰かがJava throwsキーワードのようなメソッドシグネチャを定義し、APIで特定の例外処理を強制するのではありませんユーザー。

-

個人的に、私はここで引き裂かれました。 Andersに同意しますが、例外をチェックしても、新しいさまざまな問題を追加することなく問題を解決できるわけではありません。 XMLドキュメントのコメントと同様に、try finallyブロックでラップされたすべてのC#コードはほとんど見られません。これは確かにあなたの唯一の選択肢であり、良い習慣のように思えるものですが、私には感じます。

6
Tobias

あなたはこれについて尋ねています:

例外の再スロー

public void Method()
{
  try
  {
      int x = 0;
      int sum = 100/x;
  }
  catch(DivideByZeroException e)
  {
      throw;
  }
}

または

static void Main() 
    {
        string s = null;

        if (s == null) 
        {
            throw new ArgumentNullException();
        }

        Console.Write("The string s is null"); // not executed
    }
3
Pranay Rana

実際には、C#でチェック例外を持たないことは、良いことでも悪いことでもあると考えられます。

私自身は、チェックされた例外が次の問題を提供するため、それが良い解決策であると考えています。

  1. 低レベルで適切に処理できないため、ビジネス/ドメインレイヤーに技術的な例外が漏れています。
  2. これらは、API設計で常にナイスな動作をするわけではないメソッドシグネチャに属します。

そのため、ほとんどの大規模なアプリケーションでは、チェックされた例外が発生したときに次のパターンが頻繁に表示されます。

try {
    // Some Code
} catch(SomeException ex){
    throw new RuntimeException(ex);
}

これは基本的に、C#/。NETがすべての例外を処理する方法をエミュレートすることを意味します。

3

.Net CodeContractにはいくつかのつかの間の類似点があります EnsuresOnThrow<> とJava throws記述子。両方とも関数またはメソッドから発生する可能性のある例外のタイプとして呼び出し元にシグナルを送ることができますが、また、2つの大きな違いです。

  • EnsuresOnThrow<>は、どの例外をスローできるかを指定するだけでなく、スローされることが保証される条件も規定します。例外条件を特定するのが簡単でない場合、これは呼び出されるメソッドで非常に厄介なコードになる可能性があります。 Java throwsは、どの例外がスローされる可能性があるかを示します(つまり、.Netでのフォーカスは、throwを証明するために縮約するメソッド内にあります。 in Java例外の可能性を確認するために呼び出し元にフォーカスが移動します)。
  • .Net CCは、 Checked vs Unchecked Javaが持つ例外)を区別しませんが、CCマニュアルセクション2.2.2では

「例外的な事後条件は、呼び出し元がAPIの一部として予期する例外にのみ使用してください」

  • .Netでは、呼び出し元は例外を使用して何かを行うかどうかを決定できます(たとえば、契約を無効にすることによって)。 Javaでは、呼び出し側 何かを行う必要があります (インターフェース上で同じ例外に対してthrowsを追加する場合でも)。

コード契約マニュアルはこちら

2
StuartLC