我有一个FTP类,它有一个Dipose()
方法
public class Ftp : IFtp
{
//other methods, properties and fields
public void Dispose()
{
if (_ftp.IsConnected)
_ftp.Close();
_ftp.Dispose();
_ftp = null;
}
}
这是我用来访问Ftp
类
public interface IFtp : IDisposable
{
//other methods signatures
void Dispose();
}
这是处理Ftp
使用的内容的正确和功能性方法吗?
答案 0 :(得分:3)
这适用于经常使用该课程。但是,在开始访问_ftp
引用之前,应检查Dispose
引用是否为空。通常的做法是,您应该能够多次调用{{1}}方法而不会造成任何伤害。
您可能还想在该类中添加一个Finalizer,如果使用该类的人因某种原因无法正确处理它,您可以将其丢弃。
IDisposable
interface文档中的编码示例非常完整且评论很好。
答案 1 :(得分:3)
我认为_ftp是一个IDisposable对象。如果是这样,它应该足以完成以下任务:
public class Ftp : IFtp
{
//other methods, properties and fields
public void Dispose()
{
_ftp.Dispose();
}
}
也
public interface IFtp : IDisposable
{
//other methods signatures
}
也就是说,如果您的接口继承自Dispose()
,则无需重新指定IDisposable
方法(在您的界面中),因为它已在IDisposable
中指定。
答案 2 :(得分:2)
一般参考MSDN documentation for IDisposable
interface。
MSDN IDisposable.Dispose()
documentation具体说明:
实施此方法时,请确保所有持有的资源都是 通过包含层次结构传播调用释放。对于 例如,如果对象A分配对象B,则对象B分配 一个对象C,然后A的Dispose实现必须调用B上的Dispose, 必须依次调用Dispose on C。一个对象也必须调用 如果基类实现,则调用其基类的方法 IDisposable的。
......这就是你正在做的事情。
有关设计警告的详细信息,请参阅MSDN CA1063: Implement IDisposable correctly。
假设您的基础FTP实现未受管理,那么 还应包含终结器(如果基础实现中尚未存在)。 MSDN IDisposable.Dispose()
documentation具体说明:
因为必须显式调用Dispose方法,才能调用对象 实现IDisposable还必须实现一个终结器来处理 在未调用Dispose时释放资源。
另请参阅MSDN Object.Finalize
和MSDN Implementing Finalize and Dispose to Clean Up Unmanaged Resources
如果你的继承链中没有合适的终结器,也许这就是你警告的原因?
另请注意(作为反例),Microsoft建议使用者不应直接调用Dispose()
。 MSDN using
statement documentation州:
通常,当您使用IDisposable对象时,您应该声明和 在using语句中实例化它。
使用者的首选方法是“使用”IDisposable
资源,如下所示:
using (FTP myDisposableFTP = new FTP()) {
...
}
这基本上是“语法糖”,以确保在您使用可支配资源(即Dispose()
块的结尾)时调用using
方法,或者重要的是,如果在 using
块中发生异常。
此模式还避免了对实例引用进行null
检查的要求,因为实例已在块的开头构造。它还确保无法重新分配对象(保护底层资源不会被意外打开,即使您的原始引用超出范围)。
但我认为你可以将这种模式(或等效的try / catch / finally)合并到你的继承/接口实现中是值得怀疑的。
所以是的,调用Dispose()
方法在功能上是好的,只要你记得在需要它的所有情况下调用它(例如在你的异常处理中),或者你重新暴露它的地方向您的消费者提供正确处理作为“包装”IDisposable
实现的一部分。但是如果您的资源不受管理,您还应该添加终结器。