由于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