使用关键字和IDisposable接口之间有什么关系?
-
30-09-2019 - |
题
如果我正在使用 using
关键字,我仍然必须实施 IDisposable
?
解决方案
如果您使用 using
陈述 封闭类型必须已经实现 IDisposable
否则,编译器将发布错误。因此,将IDISPOSABLE实现视为使用的先决条件。
如果您想使用 using
在您的自定义课上的声明,然后您必须实施 IDisposable
为了它。但是,这是有点落后的,因为为此而没有意义。只有当您可以实施像不受管理的资源之类的东西时,只有可以处理。
// To implement it in C#:
class MyClass : IDisposable {
// other members in you class
public void Dispose() {
// in its simplest form, but see MSDN documentation linked above
}
}
这使您能够:
using (MyClass mc = new MyClass()) {
// do some stuff with the instance...
mc.DoThis(); //all fake method calls for example
mc.DoThat();
} // Here the .Dispose method will be automatically called.
有效地与写作相同:
MyClass mc = new MyClass();
try {
// do some stuff with the instance...
mc.DoThis(); //all fake method calls for example
mc.DoThat();
}
finally { // always runs
mc.Dispose(); // Manual call.
}
其他提示
你不能没有另一个。
当你写时:
using(MyClass myObj = new MyClass())
{
myObj.SomeMthod(...);
}
编译器将生成这样的东西:
MyClass myObj = null;
try
{
myObj = new MyClass();
myObj.SomeMthod(...);
}
finally
{
if(myObj != null)
{
((IDisposable)myObj).Dispose();
}
}
因此,您可以看到 using
关键字假定/要求实现IDISPOSABLE。
你令人困惑的事情。您只能在实现Idisposable的内容上使用“使用”关键字。
编辑:如果您使用使用的关键字,则不必显式调用处置,它将在使用块的末尾自动调用。其他人已经发布了如何将使用语句转化为尝试的示例 - 最后是语句,并在最后块中调用。
是的,使用的关键字是这种类型的图案的句法糖...(来自MSDN)
Font font1 = new Font("Arial", 10.0f);
try
{
byte charset = font1.GdiCharSet;
}
finally
{
if (font1 != null)
((IDisposable)font1).Dispose();
}
编辑:一个有用的示例。
当您发现最终在一个部分中做事时,例如将光标设置为等待光标后,将光标重置为默认值时,这是此模式的候选者...
public class Busy : IDisposable
{
private Cursor _oldCursor;
private Busy()
{
_oldCursor = Cursor.Current;
}
public static Busy WaitCursor
{
get
{
Cursor.Current = Cursors.WaitCursor;
return new Busy();
}
}
#region IDisposable Members
public void Dispose()
{
Cursor.Current = _oldCursor;
}
#endregion
}
称为...
using(Busy.WaitCursor)
{
// some operation that needs a wait cursor.
}
使用只会处置 一次性的 对象。因此,在无法实现IDISPOSOPOS的对象周围包裹使用块 相当无用 实际上,会导致编译器错误。
http://msdn.microsoft.com/en-us/library/yh598w02.aspx
通常,当您使用iDisposable对象时,应在使用语句中声明并实例化。使用语句以正确的方式调用对象上的Dispose方法,并且还会导致对象本身在调用处置后立即脱离范围。在使用块中,该对象仅读取,无法修改或重新分配。
使用语句确保即使在对象上调用方法时发生异常,也会调用处置。您可以通过将对象放入尝试块中,然后呼叫将对象放入最终块中来实现相同的结果;实际上,这就是编译器翻译使用语句的方式。
您必须实现可使用的IDisposable。如果您尝试在无法实现IDisposable的类型上使用(),则会获得以下编译时间错误:
error CS1674: 'SomeType': type used in a using statement must be implicitly convertible to 'System.IDisposable'
使用的关键字已经实现,因此,如果您使用使用的关键字,则无需调用IDISPOSABLE