如果我使用using
关键字,我还需要实现IDisposable
吗?
7 回答
你不能没有另一个。
当你写:
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。
如果您使用该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.
}
你把事情弄糊涂了。您只能在实现 IDisposable 的东西上使用“using”关键字。
编辑:如果使用 using 关键字,则不必显式调用 Dispose,它将在 using 块的末尾自动调用。其他人已经发布了如何将 using 语句转换为 try - finally 语句的示例,其中 Dispose 在 finally 块中调用。
是的,using 关键字是这种模式的语法糖......(来自 msdn)
Font font1 = new Font("Arial", 10.0f);
try
{
byte charset = font1.GdiCharSet;
}
finally
{
if (font1 != null)
((IDisposable)font1).Dispose();
}
编辑:一个有用的例子。
当您发现自己在 finally 部分中始终如一地做事时,例如在将光标设置为等待光标后将其重置为默认值,这是此模式的候选者...
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.
}
使用只会处理一次性物品。因此,在未实现 IDisposable 的对象周围包装 using 块是相当无用的,实际上会导致编译器错误。
http://msdn.microsoft.com/en-us/library/yh598w02.aspx
通常,当您使用 IDisposable 对象时,您应该在 using 语句中声明和实例化它。using 语句以正确的方式调用对象上的 Dispose 方法,并且一旦调用 Dispose,它还会导致对象本身超出范围。在 using 块中,对象是只读的,不能修改或重新分配。
using 语句可确保调用 Dispose,即使在调用对象上的方法时发生异常也是如此。您可以通过将对象放在 try 块中,然后在 finally 块中调用 Dispose 来获得相同的结果;事实上,这就是编译器翻译 using 语句的方式。
using 关键字已经实现,因此如果使用 using 关键字,则不必调用 IDisposable
您必须实现 IDisposable 才能使用 using。如果您尝试在未实现 IDisposable 的类型上使用 using() ,则会收到以下编译时错误:
error CS1674: 'SomeType': type used in a using statement must be implicitly convertible to 'System.IDisposable'