この場合、の宣言はwhoAmI
パフォーマンス/スコープの点で実際には何の違いもありません。結局のところ、のプロパティアクセスwhoAmI.UserId
もに含まれている必要がありますusing
。ILの観点から見ると、この2つの機能の違いは、OrganizationalServiceProxy.Dispose
メソッドが呼び出される順序と、にWhoAmIResponse.UserId
アクセスするタイミングだけです。
(編集:デフォルト値を返すための処理方法に実際の問題はないと思います。それtry/catch
は質問の一部ではないようですので、これも省略されています)
投稿されたコード(ILを明確にするために簡略化):
public Guid IsServerReachableOutsideUsingScope()
{
WhoAmIResponse whoAmI;
using(var service = new Service())
whoAmI = service.Execute();
return whoAmI.UserId;
}
次のILの結果:
IL_0000: newobj UserQuery+Service..ctor
IL_0005: stloc.1 // service
IL_0006: ldloc.1 // service
IL_0007: callvirt UserQuery+Service.Execute
IL_000C: stloc.0 // whoAmI
IL_000D: leave.s IL_0019
IL_000F: ldloc.1 // service
IL_0010: brfalse.s IL_0018
IL_0012: ldloc.1 // service
IL_0013: callvirt System.IDisposable.Dispose
IL_0018: endfinally
IL_0019: ldloc.0 // whoAmI
IL_001A: callvirt UserQuery+WhoAmIResponse.get_UserId
IL_001F: ret
usingブロック内のすべてを宣言するのに対して:
public Guid IsServerReachableWithinUsingScope()
{
using(var service = new Service())
{
WhoAmIResponse whoAmI = service.Execute();
return whoAmI.UserId;
}
}
ILを生成します:
IL_0000: newobj UserQuery+Service..ctor
IL_0005: stloc.0 // service
IL_0006: ldloc.0 // service
IL_0007: callvirt UserQuery+Service.Execute
IL_000C: stloc.1 // whoAmI
IL_000D: ldloc.1 // whoAmI
IL_000E: callvirt UserQuery+WhoAmIResponse.get_UserId
IL_0013: stloc.2 // CS$1$0000
IL_0014: leave.s IL_0020
IL_0016: ldloc.0 // service
IL_0017: brfalse.s IL_001F
IL_0019: ldloc.0 // service
IL_001A: callvirt System.IDisposable.Dispose
IL_001F: endfinally
IL_0020: ldloc.2 // CS$1$0000
IL_0021: ret
プロパティにアクセスする前にサービスを破棄しないことが重要な場合(たとえば、NHibernateの遅延ロードされたコレクションのコンテキストで)、順序は間違いなく重要です。それが問題ではない場合、最大の問題はあなたとあなたのチームが最も気にかけていることです。呼び出しの混合と一致を気にせず、中かっこがあるものとないものがある場合は、持っているものを続行します。using
おそらくWhoAmIResponse.UserId
、アクセスに副作用がある場合に考慮すべきことは、例外処理の順序です。サービスの呼び出しが例外をスローした場合、元のコード( )では、プロパティにアクセスしたことがないため、副作用が実行されることはありません。コードの2番目のブロック( )では、プロパティを使用することによる副作用にアクセスして実行し、次に例外をスローするを実行します。Dispose
IsServerReachableOutsideUsingScope
IsServerReachableWithinUsingScope
UserId
Dispose
これらはかなりまれなケースです(編集:get-accessの副作用とDispose()
例外のスローの両方が悪い習慣と見なされることに注意してください)。ここでそれが当てはまる場合は、これらを正しく検討する必要があります。これらが問題ではない場合(副作用がなく、アクセス/廃棄の順序を気にしない)、長期的にはあなたとあなたのチームがより保守可能/読みやすいと感じるものを使用してください。