Javaでは、このthrows
キーワードにより、メソッドはそれ自体では例外を処理せず、呼び出し元のメソッドに例外をスローすることを宣言できます。
C#に同様のキーワード/属性はありますか?
同等のものがない場合、どのようにして同じ(または類似の)効果を達成できますか?
回答:
Javaでは、例外を処理するか、throws
キーワードを使用してメソッドをスローする可能性があるメソッドとしてメソッドをマークする必要があります。
C#にはこのキーワードまたは同等のキーワードがありません。C#のように、例外を処理しないと、キャッチされるまで、またはキャッチされない場合はプログラムが終了するまで、バブルアップします。
それを処理したい場合は、次のように再スローできます:
try
{
// code that throws an exception
}
catch(ArgumentNullException ex)
{
// code that handles the exception
throw;
}
opは、キーワードではなく、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...
}
はい、これは古いスレッドですが、答えをググるときに古いスレッドを頻繁に見つけるので、見つけた便利なものを追加すると思いました。
Visual Studio 2012を使用している場合は、IDEレベルの「スロー」相当を可能にするために使用できる組み込みツールがあります。
上記のようにXML Documentation Commentsを使用する場合、<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);
}
throws
していますが、JAVAはおそらく、開発者に情報を提供することを除いて、ランタイムにとって何の意味もありません。同様に、@ mvanellaがここで指摘したのは、C#でまったく同じことを行う方法です。この "xmlドキュメント"の方がより重要な目的があることを知っていると思います。このスレッドは古いことを知っています。
throws
節で明示的に指定されていないか、throw
コマンドによってスローされない限り、例外をバブルアップしません。つまり、RunTimeExceptionが発生し、発生したのと同じメソッドで処理されない場合、実行はそこで停止します。
これが私がbytes.comで見つけた同様の質問への回答です。
短い答えはノーです。C#にはチェック済みの例外はありません。言語の設計者は、このインタビューでこの決定について議論します。
http://www.artima.com/intv/handcuffs.html
あなたが得ることができる最も近いのは、XMLドキュメントでタグを使用し、NDocで生成されたドキュメントをコード/アセンブリと共に配布して、他の人があなたがスローした例外を確認できるようにすることです(これは、MSDNドキュメントで正確にMSが行っていることです)。未処理の例外についてコンパイラに通知することはできませんが、Javaで慣れている場合と同様です。
ここでほとんどの回答を終えた後、いくつかの考えを追加したいと思います。
XMLドキュメントのコメントに依存し、他の人に依存することを期待するのは適切な選択ではありません。私が出会ったほとんどのC#コードは、XMLドキュメントコメントでメソッドを完全かつ一貫してドキュメント化していません。そして、C#でチェックされた例外がなければ、APIユーザーがそれらすべてを個別に処理する方法を知るためにメソッドがスローするすべての例外をどのように文書化できるかという大きな問題がありますか?覚えているのは、実装でthrowキーワードを使用して自分で投げたものについてのみ知っていることです。メソッドの実装内で使用しているAPIは、ドキュメントに記載されていない可能性があり、実装でそれらを処理していないため、知らない例外をスローする可能性があります。方法。言い換えると、
Andreasは、C#設計チームがチェックされた例外に反対する理由をここで答えたAnders Hejlsbergへのインタビューをリンクしました。元の質問に対する最終的な応答は、そのインタビューに隠されています。
プログラマーは、try finallyをどこにでも書いてコードを保護するため、例外が発生した場合に正しくバックアウトしますが、実際には例外の処理には関心がありません。
つまり、すべての場所で常にすべてのAPIをキャッチするため、特定のAPIでどのような例外が発生する可能性があるのかを誰も気にする必要はありません。特定の例外を本当に気にかけたい場合、それらを処理する方法はあなた次第であり、Javaのthrowsキーワードなどでメソッドシグネチャを定義して、APIユーザーに特定の例外処理を強制するのではありません。
-
個人的に、私はここで引き裂かれています。例外をチェックしても問題が解決されないのは、新しい別の問題を追加しない限り、アンダース氏に同意する。XMLドキュメントのコメントと同じように、C#のコードで、すべてがtry finallyブロックにラップされているのはめったにありません。これは確かにあなたの唯一の選択肢であり、良い習慣のように思えるものですが、それは私には感じられます。
実際にC#で例外をチェックしなかったのは、良いことでも悪いことでもあります。
チェックされた例外は次の問題を提供するので、私自身はそれが良い解決策であると考えています:
そのため、ほとんどの大きなアプリケーションでは、チェックされた例外が発生すると、次のパターンが頻繁に表示されます。
try {
// Some Code
} catch(SomeException ex){
throw new RuntimeException(ex);
}
これは基本的に、C#/。NETがすべての例外を処理する方法をエミュレートすることを意味します。
あなたはこれについて尋ねています:
例外の再スロー
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
}
throw
。それを使用することにより、スタックトレースが失われることはありません。
.Net CodeContract EnsuresOnThrow<>
とjava throws
記述子の間には、いくつかの一時的な類似点があります。どちらも、関数またはメソッドから発生する可能性のある例外のタイプとして呼び出し元に通知できますが、2には大きな違いもあります。
EnsuresOnThrow<>
どの例外をスローできるかを示すだけでなく、例外がスローされることが保証されている条件も規定しています。例外条件を特定するのが簡単ではない場合、これは呼び出されたメソッドで非常に面倒なコードになる可能性があります。Java throws
は、どの例外がスローされる可能性があるかを示します(つまり、.MOでのフォーカスは、throw
、ありますが、Javaの場合、フォーカスは呼び出し元に移り、例外の可能性を確認します)。「例外的な事後条件は、呼び出し元がAPIの一部として予期する必要がある例外にのみ使用してください」
throws
、インターフェイスに同じ例外のを追加した場合でも、何かを行う必要があります。c#メソッドの目的が例外のみをスローすることである場合(jsの戻り値の型のように)、その例外を返すことをお勧めします。以下の例をご覧ください。
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;
}
不思議に思う人のために、次のメソッドに渡すために何をキャッチするかを定義する必要さえありません。1つのメインスレッドですべてのエラー処理が必要な場合は、次のようにすべてをキャッチして渡すことができます。
try {
//your code here
}
catch {
//this will throw any exceptions caught by this try/catch
throw;
}