在我的公司,我看到这样的代码
using (LoggerFactory.GetTracer(_log.ModuleName + "._GetAccessTokenFromWns"))
{...}
当我抬起头时,我学会了它处理由“使用”括号内声明的变量引用的对象。
对于上面的代码,它是否也有帮助,那里没有引用工厂返回的对象的变量?
谢谢,
答案 0 :(得分:4)
在看到你的问题后,我写了一个简单的代码:
using (new FileStream("sample.txt",FileMode.CreateNew))
{
}
然后我看一下制作的IL code
:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 35 (0x23)
.maxstack 2
.locals init ([0] class [mscorlib]System.IO.FileStream CS$3$0000,
[1] bool CS$4$0001)
IL_0000: nop
IL_0001: ldstr "asdas.txt"
IL_0006: ldc.i4.1
IL_0007: newobj instance void [mscorlib]System.IO.FileStream::.ctor(string,
valuetype [mscorlib]System.IO.FileMode)
IL_000c: stloc.0
.try
{
IL_000d: nop
IL_000e: nop
IL_000f: leave.s IL_0021
} // end .try
finally
{
IL_0011: ldloc.0
IL_0012: ldnull
IL_0013: ceq
IL_0015: stloc.1
IL_0016: ldloc.1
IL_0017: brtrue.s IL_0020
IL_0019: ldloc.0
IL_001a: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_001f: nop
IL_0020: endfinally
} // end handler
IL_0021: nop
IL_0022: ret
} // end of method Program::Main
正如您所看到它仍在调用Dispose
方法。它会在FileStream
阻止之前创建try
实例,然后在Dispose
中调用finally
方法我认为这是using
语句的另一个优点。
答案 1 :(得分:3)
对象的“处置”涉及清理它可能已初始化以供自己使用的任何资源。重要的任务不是清理引用,而是清除文件锁,互斥锁等。
答案 2 :(得分:3)
这是确保处理对象而不为其引入变量的唯一方法。这与
相同var __invisible = LoggerFactory.GetTracer(_log.ModuleName + "._GetAccessTokenFromWns");
try {
} finally {
__invisible.Dispose();
}
但没有__invisible
变量。
当不需要变量时,这种结构特别有用,因为熟悉这个习语的读者会发现这样的代码更具可读性。
答案 3 :(得分:2)
我相信它仍然具有同样的效果。如果GetTracer
正在返回实现IDisposable
的类的实例,那么此代码将确保正确处理该实例。仅仅因为没有返回值的分配并不意味着没有分配需要处置的资源。例如,跟踪器可能正在打开一个文件而没有using
语句,即文件锁/ streamreader或者我不知道的任何资源。