catch
ブロックなしでtry-finally
ブロックを使用するのが適切な状況はありますか?
これを使用して、try
コンテンツの後または例外でいくつかのアクションが発生することを保証しますが、その例外を消費したくない場合に使用します。
明確にするために、これは例外を隠しません。 finally
ブロックは、例外が呼び出しスタックに伝播される前に実行されます。
using
キーワードを使用する場合、これはtry-finally
にコンパイルされるため(不正確な変換ではありませんが、引数のために十分近いため)、誤って使用することもあります。
try
{
TrySomeCodeThatMightException();
}
finally
{
CleanupEvenOnFailure();
}
finally
で実行されるコードの実行は保証されませんが、保証されない場合はかなりエッジです-覚えていません。私が覚えているのは、その場合、finally
を実行しないことがあなたの最大の問題ではない可能性が非常に高いことです:-)基本的には汗をかかないでください。
Tobiasからの更新:finally
は、プロセスが強制終了されると実行されません。
Paddyからの更新:最終的に.net try..finallyブロックで実行されない場合の条件
最もよく見られる例は、コードが失敗した場合でも、データベース接続または外部リソースを破棄することです。
using (var conn = new SqlConnection("")) // Ignore the fact we likely use ORM ;-)
{
// Do stuff.
}
次のようにsomethingにコンパイルします:
SqlConnection conn;
try
{
conn = new SqlConnection("");
// Do stuff.
}
finally
{
if (conn != null)
conn.Dispose();
}
using
はtry-finally
と同等です。 finally
内で何らかのクリーンアップを行い、例外を気にしない場合にのみ、try-finally
を使用します。
ベストアプローチは
try
{
using(resource)
{
//Do something here
}
}catch(Exception)
{
//Handle Error
}
using
によって呼び出されるクリーンアップも失敗しますが、コードは失敗しません。
finally
が実行されない条件がいくつかあります。
StackOverflowException
またはExecutingEngineException
がある場合。これがあなたの疑問に答えることを願っています。
たとえば、tryブロックで作成して使用するアンマネージリソースがある場合、finallyブロックを使用して、そのリソースを確実に解放できます。 finallyブロックは、tryブロックで何が起こっても(例外など)常に実行されます。
例えば。 lock(x)ステートメントは本当に:
System.Threading.Monitor.Enter(x);
try { ... }
finally
{
System.Threading.Monitor.Exit(x);
}
Finallyブロックは、排他ロックが確実に解放されるように常に呼び出されます。
コードを使用した説明:
void MyMethod1()
{
try
{
MyMethod2();
MyMethod3();
}
catch(Exception e)
{
//do something with the exception
}
}
void MyMethod2()
{
try
{
//perform actions that need cleaning up
}
finally
{
//clean up
}
}
void MyMethod3()
{
//do something
}
MyMethod2またはMyMethod3のいずれかが例外をスローすると、MyMethod1によってキャッチされます。ただし、MyMethod2のコードはクリーンアップコードを実行する必要があります。例外がMyMethod1に渡される前に、データベース接続を閉じます。
最後にtryを使用したい場合があります。通常はusingステートメントを使用しますが、リフレクションによってメソッドを呼び出しているため使用できません。
これは機能しません
using (objMsg = Activator.CreateInstance(TypeAssist.GetTypeFromTypeName("omApp.MessagingBO")))
{
}
代わりに使用する
object objMsg = null;
try
{
objMsg
= Activator.CreateInstance(TypeAssist.GetTypeFromTypeName("myAssembly.objBO"));
strResponse = (string)objMsg.GetType().InvokeMember("MyMethod", BindingFlags.Public
| BindingFlags.Instance | BindingFlags.InvokeMethod, null, objMsg,
new object[] { vxmlRequest.OuterXml });
}
finally
{
if (objMsg!=null)
((IDisposable)objMsg).Dispose();
}
どの例外がキャッチされたとしても、キャッチされなかったとしても、ブロックが終了する前にコードを実行したい場合は、finallyブロックが必要です。たとえば、開いているファイルを閉じたい場合があります。
関連項目 try-finally
try/finally:例外を処理したくないが、呼び出されたコードによって例外がスローされたかどうかにかかわらず、何らかのアクションが発生することを確認したい場合。
次のリンクをご覧ください: https://softwareengineering.stackexchange.com/questions/131397/why-use-try-finally-without-a-catch-clause
それは、アプリケーションのアーキテクチャと、ブロックで実行する操作に依存します。
これが私がいつも(ええと..)使用するユースケースです:
int? x; //note the nullable type here!
try
{
x = int.Parse(someString);
}
catch { } //don't care, let it just be null
私はC#について何も知りませんが、try-finallyでできることは何でも、 sing statement でもっとエレガントにできると思われます。 C++には、最終的に RAIIの結果 がありません。
1. catchなしでtryブロックを使用できますが、catch/finallyのいずれかを使用する必要があります。 2. tryブロックのみを使用することはできません。