我有一个带析构函数的类,我得到一个空引用异常,因为我有时会销毁变量null.
这是null条件运算符在析构函数中的适当用法吗?
我甚至不确定这是否适合使用析构函数本身,因为它不是用于处理它所调用的实际对象而是用于处理它的变量.
~clsSAPSettings()
{
mtbTemp?.Close();
}
Run Code Online (Sandbox Code Playgroud)
这段代码是从VB6转换而来的,所以我想弄清楚如何处理这个问题.欢迎任何信息.
编辑:该类mtbTemp属于implements,IDisposable但没有 finaliser/desctructor.它只是关闭ORM模型中使用的连接.
对于任何人在详细解释后,我找到了一个很好的答案,正确使用IDisposable接口,它详细介绍了终结器的使用以及垃圾收集实际如何工作.
请不要在终结器中使用任何引用类型的字段:GC(垃圾收集器)收集它们的顺序是不可预测的,这就是为什么
~clsSAPSettings()
{
mtbTemp?.Close();
}
Run Code Online (Sandbox Code Playgroud)
GC可以很好地执行代码,如下所示:
mtbTemp实例this实例:~clsSAPSettings()mtbTemp?.Close();的方法你会遇到一个不稳定的难以发现的错误。看来您正在寻找一个IDisposable接口:
public class clsSAPSettings: IDisposable {
private MyTemp mtbTemp;
...
protected virtual void Dispose(bool disposing) {
if (disposing) {
mtbTemp?.Close();
GC.SuppressFinalize(this);
}
}
public void Dispose() {
Dispose(true);
}
//TODO: do you really want finalizer?
~clsSAPSettings() {
Dispose(false);
}
}
Run Code Online (Sandbox Code Playgroud)
考虑:
~clsSAPSettings()
{
mtbTemp?.Close();
}
Run Code Online (Sandbox Code Playgroud)
这里的问题不是null条件用法.这本身并不存在任何问题.
最大的问题是在终结器中你不应该碰到任何其他物体.当终结者开火时,你的对象就是吐司.您不再对生命有任何保证mtbTemp,包括它是否已被垃圾收集,因此您不应该触摸它.它可能有用; 它可能会导致暂时的复活,或者它可能会崩溃.
这样做的正确的地方是IDisposable.Dispose.在Dispose方法中,这绝对是好的:
public void Dispose() // where your class : IDisposable
{
mtbTemp?.Close();
mtbTemp = null;
}
Run Code Online (Sandbox Code Playgroud)
你可能根本不需要终结器.它们非常罕见.
| 归档时间: |
|
| 查看次数: |
139 次 |
| 最近记录: |