110

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

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

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

4

10 に答える 10

128

オペレーションは、キーワードではなく、Javaのthrowsに相当するC#について質問しています。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...
}
于 2010-08-12T12:07:58.353 に答える
90

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

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

それを処理したい場合は、次のように再スローできます。

try
{
  // code that throws an exception
}
catch(ArgumentNullException ex)
{
  // code that handles the exception
  throw;
}
于 2010-08-12T07:17:06.143 に答える
47

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

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);
    }
于 2013-07-23T12:37:19.733 に答える
20

これがbytes.comで見つけた同様の質問に対する答えです:

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

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

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

于 2010-08-12T07:24:06.293 に答える
8

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

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

  2. Andreasは、C#設計チームがチェックされた例外に反対することを決定した理由についての回答でAndersHejlsbergとのインタビューをリンクしました。元の質問に対する最終的な回答は、そのインタビューに隠されています。

プログラマーはtryfinallyをどこにでも書くことでコードを保護するため、例外が発生した場合は正しくバックアウトしますが、実際には例外の処理には関心がありません。

つまり、特定のAPIでどのような例外が発生する可能性があるかについては、誰も気にする必要はありません。常にすべてのAPIをキャッチするからです。また、特定の例外を本当に気にしたい場合、それらを処理する方法はあなた次第であり、Java throwsキーワードのようなものでメソッドシグネチャを定義し、APIユーザーに特定の例外処理を強制する人ではありません。

-

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

于 2017-05-24T22:39:17.923 に答える
3

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

例外を再スローする

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
    }
于 2010-08-12T07:18:01.960 に答える
3

実際、C#で例外をチェックしていないことは、良いことでも悪いことでもあります。

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

  1. 技術的な例外は、低レベルで適切に処理できないため、ビジネス/ドメインレイヤーにリークします。
  2. これらはメソッドシグネチャに属しており、API設計で常にうまく機能するとは限りません。

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

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

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

于 2010-08-12T07:50:49.917 に答える
2

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

  • EnsuresOnThrow<>どの例外をスローできるかを示すだけでなく、それらがスローされることが保証される条件も規定します。例外条件を特定するのが簡単でない場合、これは呼び出されたメソッドで非常に面倒なコードになる可能性があります。Javathrowsは、どの例外がスローされる可能性があるかを示します(つまり、.NetのIMOフォーカスは、を証明するためにコントラクトするメソッド内にありthrowますが、Javaでは、例外の可能性を確認するために呼び出し元にフォーカスが移ります)。
  • .Net CCは、Javaのチェックされた例外とチェックされていない例外を区別しませんが、CCのマニュアルセクション2.2.2には次のように記載されています。

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

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

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

于 2013-09-18T10:07:04.403 に答える
1

c#メソッドの目的が例外をスローすることだけである場合(js return typeが言うように)、その例外を返すことをお勧めします。次の例を参照してください。

    public EntityNotFoundException GetEntityNotFoundException(Type entityType, object id)
    {
        return new EntityNotFoundException($"The object '{entityType.Name}' with given id '{id}' not found.");
    }

    public TEntity GetEntity<TEntity>(string id)
    {
        var entity = session.Get<TEntity>(id);
        if (entity == null)
            throw GetEntityNotFoundException(typeof(TEntity), id);
        return entity;
    }

于 2019-11-13T10:54:40.907 に答える
-1

疑問に思っている人のために、次のメソッドに渡すためにキャッチするものを定義する必要さえありません。1つのメインスレッドですべてのエラー処理が必要な場合は、すべてをキャッチして、次のように渡すことができます。

try {
    //your code here
}
catch {
    //this will throw any exceptions caught by this try/catch
    throw;
}
于 2020-01-17T09:09:21.607 に答える