很多公司的面试都可能问或是考查这个看似基础的东西,恕我浑浑噩噩,我可能回答的不够好!习惯性质的是由于我可能知道一些东西,但由于事务缠身,并没有去过多的关注部分细节,其间也没有得到某些无意或是有意的灌输,我可能会回答区别在于一个不会自动释放资源,一个会。那USING为甚么会了?在甚么时候使用USING合适等。
我不知道在后面的回答是否都能把握的好,这只能说明我不够精通,但这些题目从来就没有给别人这样一个机会,假如你回答的不好,你是否能通过一种途径来找出区别,然后你再重新回答。
我笑了,假如我回答的不够好,我觉得后面是一个机会(也是一种能力的考察),我会通过甚么途径了,ILDASM,至少我知道我们生活再.NET的“蜜糖”中,我们有了好的高层次的框架,我有了很好的开发效率,但我忽视了细节,有很多时候,甚至懒得去关心细节,但这个题目让我觉得很丢脸,我回答的不好(阴沟里还翻了船) ,但我自知,秘密就藏再后面,于是我解开一段DEMO,看个明白。
namespace Demo
{
class Class1
{
[STAThread]
static void Main( string [] args)
{
Test obj1 = new Test();
using (Test obj2 = new Test())
{
}
}
}
class Test:System.IDisposable
{
int a;
public int Val
{
get
{
return a;
}
}
#region IDisposable Members
public void Dispose()
{
}
#endregion
}
}
上面代码对应的IL语言解开了USING的秘密:
{
.entrypoint
.custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 )
// Code size 25 (0x19)
.maxstack 1 ---推导堆栈
.locals init ([ 0 ] class Demo.Test obj1,
[ 1 ] class Demo.Test obj2) --定义了两局部变量
IL_0000: newobj instance void Demo.Test::.ctor()
IL_0005: stloc. 0 -- 创建了Test对象并存放到 第一个局部量
IL_0006: newobj instance void Demo.Test::.ctor()
IL_000b: stloc. 1 -- 创建了Test对象并存放到第二个局部量
. try
{
IL_000c: leave.s IL_0018 -- 你可以看作是GOTO语句 ,但是你要清楚,异常和RETURN,GOTO都不能逃出FINALLY
} // end .try FINALLY是一定会执行
finally
{
IL_000e: ldloc. 1 --载入局部量1,也是就我们用USING扩起的那个局部量)
IL_000f: brfalse.s IL_0017 --发现,如果这个对象是NULL的,就结束 ,否则就调用对象上的DISPOSE方法,哦原来如此
IL_0011: ldloc. 1 -- 我们终于发现了秘密, ^_^ ,假如面试前你正好研究过,你回答的是否就更清晰!
IL_0012: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_0017: endfinally
} // end handler
IL_0018: ret
} // end of method Class1::Main
现在我要回答后面的问题了,是框架帮我做了手脚,他强制帮我调用对象的DISPOSE资源释放方法,而且,如果你的对象没有实现此IDISPOSABLE接口,却用了USING,编译是不会通过的哟!这里看来,USING的时机是当对象使用了非托管资源或是比较宝贵的资源,
而对于托管的或非宝贵的资源,我可以依赖GC(垃圾回收机制,garbage collection),没有必要自己画蛇添足。而且TRY块是会影响效率的。
转自:http://www.cnblogs.com/bytekiller/archive/2007/06/21/792411.html