有没有一种方法或其他一些轻量级的方法来检查引用是否是对已处理对象的引用?
PS - 这只是一个好奇(睡得好,不是在生产代码中)。是的,我知道我可以ObjectDisposedException
在尝试访问对象的成员时捕捉到。
有没有一种方法或其他一些轻量级的方法来检查引用是否是对已处理对象的引用?
PS - 这只是一个好奇(睡得好,不是在生产代码中)。是的,我知道我可以ObjectDisposedException
在尝试访问对象的成员时捕捉到。
否 - IDisposable 模式的默认实现不支持它
System.Windows.Forms.Control
有一个在被调用后设置为 trueIsDisposed
的属性。在您自己的 IDisposable 对象中,您可以轻松地创建类似的属性。Dispose()
没有内置的东西可以允许这样做。您需要公开一个反映内部已处置标志的 IsDisposed 布尔属性。
public class SimpleCleanup : IDisposable
{
private bool disposed = false;
public bool IsDisposed
{
get
{
return disposed;
}
}
public SimpleCleanup()
{
this.handle = /*...*/;
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// free only managed resources here
}
// free unmanaged resources here
disposed = true;
}
}
public void Dispose()
{
Dispose(true);
}
}
如果它不是你的类并且它不提供 IsDisposed 属性(或类似的东西 - 名称只是一个约定),那么你无法知道。
但是,如果它是您的班级并且您正在遵循规范的 IDisposable 实现,那么只需将 _disposed 或 _isDisposed 字段作为属性公开并检查它。
我看到这是旧的,但我没有看到答案。并非所有一次性对象(如 DataSet)都具有可以附加的已处置事件。
class DisposeSample : IDisposable
{
DataSet myDataSet = new DataSet();
private bool _isDisposed;
public DisposeSample()
{
// attach dispose event for myDataSet
myDataSet.Disposed += MyDataSet_Disposed;
}
private void MyDataSet_Disposed(object sender, EventArgs e)
{
//Event triggers when myDataSet is disposed
_isDisposed = true; // set private bool variable as true
}
public void Dispose()
{
if (!_isDisposed) // only dispose if has not been disposed;
myDataSet?.Dispose(); // only dispose if myDataSet is not null;
}
}
该Dispose
方法需要在对象被放弃之前执行任何清理工作;如果不需要清理,则不需要执行任何操作。要求一个对象跟踪它是否已被释放,即使该Dispose
方法不做任何事情,也将需要许多IDisposable
对象添加一个标志,以获得非常有限的好处。
如果IDisposable
包含两个属性可能会有所帮助 - 一个指示对象是否需要处置,其中一个指示对象没有被处置而变得无用。对于处理实际上做某事的对象,两个值最初都是 true,之后会变为 false Dispose
。对于处理不需要进行任何清理的对象,第一个方法总是可以返回 false,而第二个方法总是返回 true,而不必在任何地方存储标志。不过,我认为现在无法将它们添加到 .NET 中。
检查对象是否使用 Extension 方法处理的快捷方式可能是
public static class ObjectExtensions
{
public static bool IsDisposed(this object obj)
{
try
{
obj.ToString();
return false;
}
catch (ObjectDisposedException)
{
return true;
}
}
}
//Usage
if(myObject.IsDisposed()){
/* Do your Stuff */
}
我喜欢做的是声明对象而不初始化它们,但将它们的默认值设置为Nothing
. 然后,在循环结束时我写:
If anObject IsNot Nothing Then anObject.Dispose()
这是一个完整的示例:
Public Sub Example()
Dim inputPdf As PdfReader = Nothing, inputDoc As Document = Nothing, outputWriter As PdfWriter = Nothing
'code goes here that may or may not end up using all three objects,
' such as when I see that there aren't enough pages in the pdf once I open
' the pdfreader and then abort by jumping to my cleanup routine using a goto ..
GoodExit:
If inputPdf IsNot Nothing Then inputPdf.Dispose()
If inputDoc IsNot Nothing Then inputDoc.Dispose()
If outputWriter IsNot Nothing Then outputWriter.Dispose()
End Sub
这也适用于将主要对象放在例程的顶部,在例程中使用它们Try
,然后将它们放置在一个Finally
块中:
Private Sub Test()
Dim aForm As System.Windows.Forms.Form = Nothing
Try
Dim sName As String = aForm.Name 'null ref should occur
Catch ex As Exception
'got null exception, no doubt
Finally
'proper disposal occurs, error or no error, initialized or not..
If aForm IsNot Nothing Then aForm.Dispose()
End Try
End Sub