试图了解何时需要实施IDisposable:
我写了一个小例子。 public class FileManager
{
private FileStream fileStream;
public void OpenFile(string path)
{
this.fileStream = File.Open(path, FileMode.Open, FileAccess.Read);
}
public void CloseFile(string path)
{
if ( this.fileStream != null && this.fileStream.CanRead)
{
this.fileStream.Close();
}
this.fileStream.Dispose();
}
}
// client
var manager = new FileManager();
manager.Open("path");
manager.Close("path");
这个类是否需要实现IDisposable,因为它有一个托管资源(FileStream),它保存在非托管资源(文件)上?或者我不必实现IDisposable,因为我正在课堂上清理?
混淆。
答案 0 :(得分:5)
对于实现IDisposable
并且可能以非平凡方式执行此操作的任何类型的每个实例,它必须始终能够识别该实例将如何Dispose
d。在大多数情况下,这意味着每个IDisposable
实例都有一个明确定义的所有者,负责调用Dispose
。对于班级创建的FileStream
实例,您的班级是所有者,因为其他任何内容都无法Dispose
。
带有引用他们拥有的IDisposable
实例 的字段的类应该几乎总是实现IDisposable
,并使用他们的Dispose
方法Dispose
他们拥有的IDisposable
个对象。你的班级有这样一个领域;因此,它应该实现IDisposable
。
只要有可能,应该设计一个需要清理的类,以便在其上调用IDisposable.Dispose
就足以执行可能需要的任何和所有这样的清理。在某些情况下,在不使用其他方法的情况下执行清理可能是不切实际的,但这些情况非常罕见。如果可以设计一个类,以便Dispose
将负责所有必要的清理,那么应该这样做。
答案 1 :(得分:1)
如果您(或其他开发人员)使用您的FileManager类而忘记关闭它,您可能希望实现IDisposable。请注意IDisposable的示例如何在终结器中调用Dispose(false)
。
答案 2 :(得分:1)
为什么要将路径传递给close方法?在您的情况下,似乎您的经理可以打开不同的文件,如果他们在打开另一个文件之前关闭,所以您不希望处置该对象。
恕我直言,我更愿意这样实现:public class FileManager : IDisposable
{
private string path;
private FileStream fileStream;
public FileManager(string path)
{
this.path = path;
}
public void OpenFile()
{
this.fileStream = File.Open(path, FileMode.Open, FileAccess.Read);
}
public void CloseFile()
{
if ( this.fileStream != null && this.fileStream.CanRead)
{
this.fileStream.Close();
this.fileStream.Dispose();
}
}
public void Dispose(){
this.CloseFile();
}
}
// client
var manager = new FileManager("path")){
manager.OpenFile();
//Do other stuff
manager.CloseFile()
或
using( var manager = new FileManager("path")){
manager.OpenFile();
//Do other stuff
}
答案 3 :(得分:1)
如果您调用Close
方法,则无需单独处理。但是,在这种情况下的一般做法是实现IDisposable
,因为无法保证该类的消费者会调用Close
。
如果创建资源然后在同一方法中处置资源,您只能可靠地省略IDisposable
,因为这是确保资源在使用后明确处置的唯一方法。
答案 4 :(得分:1)
您应该实现IDisposable。
想象:
var manager = new FileManager();
manager.Open("path"); // <- throws for some reason
manager.Close(); // <- then this never gets called
当然,您现在可以尝试/最终围绕它:
try {
var manager = new FileManager();
manager.Open("path");
}
finally {
manager.Close();
}
...但这正是发明使用和IDisposable的原因,你可以用它来舒适地写:
using (var manager = new Manager()) {
manager.OpenFile("path");
} // and CloseFile will automagically be called here.
答案 5 :(得分:0)
在这里实现IDisposable
时,看不到任何真正的好处,如果不是声明性的话。如果有人看到你的类实现IDisposable
,他就会明白在使用后必须清理某些资源。它只是一个内置的.net
声明类似的类型。
如果您不使用该模式,您可以自由地执行此操作,但是您违反了建议,并且主要是针对.net
类型声明的社区指南。