由於whoAmI
的聲明在這種情況下在性能/範圍界定方面沒有任何區別。所有它真正歸結爲whoAmI.UserId
的財產訪問也應包含在using
。從IL的角度來看,兩者之間唯一的區別在於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
儘管全光照內聲明的一切克塊:
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
有副作用,可能需要考慮的是異常處理的順序。 如果Dispose
對您的服務的調用引發異常,那麼在您的原始代碼(IsServerReachableOutsideUsingScope
)中,它將永遠不會訪問您的屬性,從而永遠不會執行其副作用。在第二個代碼塊(IsServerReachableWithinUsingScope
)中,它將訪問並執行使用UserId
屬性的然後運行Dispose
的副作用,這會引發異常。
這是相當罕見的情況下(編輯:它應該指出的是獲得接入的副作用和Dispose()
拋出異常都被認爲是不好的做法),我會建議如果它是在這裏的話,那麼你應該考慮這些是否正確。如果這些都是非問題(無副作用,不關心訪問/處置的順序),那麼從長遠來看,使用你和你的團隊的感覺是更易於維護/可讀的。
OrganizationService將被丟棄(如果它實現了IDisposed),但它將WhoAmI引用OrganizationService。因此,自從它被處置後,你將不會得到任何回報!您需要在使用聲明中返回。 – Dave 2013-03-20 14:16:40
如果變量whoAmI的整個範圍是使用塊(缺少括號會使事情在這裏混淆一點),那麼執行'return whoAmI'時甚至不會出現這種情況。 – 2013-03-20 14:18:09
我沒有看到它是如何重要的,如果你包括所有三行(聲明,任務和返回) – 2013-03-20 14:19:42