[英]How to properly design objects with internal references to disposable objects
假设我有以下课程:
public class DisposableObj : IDisposable
{
public ChildObj CreateObj();
internal object GetSomething();
// ...
}
public class ChildObj
{
private DisposableObj m_provider;
public void DoSomething()
{
m_provider.GetSomething();
}
// ...
}
在某个时候可能会丢弃一次性对象,但子对象仍然会引用它。
如果此时用户将调用DoSomething
方法,则子对象将尝试访问已处置的对象。 这不好,因此存在一个问题:
我应该如何正确设计此类课程?
UPDATE /澄清:
我知道ObjectDisposedException和所有。 我的问题可能听起来像是:如何正确通知用户有关异常情况的信息,以及如何设计类以使其更容易维护?
首先想到的是:
为您的ChildObj类提供一个内部的Boolean属性,称为ProviderDisposed。
从DisposableObj中的Dispose将此属性设置为true
但是,您应该保留创建的对象的列表,以将每个对象的已处置状态都传达给每个对象。
List<ChildObj> childsCreated = new List<ChildObj>();
public ChildObj CreateObj()
{
ChildObj obj = new ChildObj();
childsCreated.Add(obj);
return obj;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
// Check to see if Dispose has already been called.
if(!this.disposed)
{
if(disposing)
{
foreach(ChildObj obj in childsCreated)
obj.ProviderDisposed = true;
childsCreated = null;
}
disposed = true;
}
}
public class ChildObj
{
private DisposableObj m_provider;
private bool m_providerDisposed = false;
public bool ProviderDisposed
{ set { m_providerDisposed = true; } }
public void DoSomething()
{
if(m_providerDisposed == false)
m_provider.GetSomething();
// else // as from **@BrokenGlass answer**
// throw new ObjectDisposedException();
}
// ...
}
尽管从技术上讲这是一个可能的方案,但这在您的程序中应该是一个例外状态-我无法想象您为什么会故意为此方案设置。
话虽如此,这在您的设计中明确指出了谁负责处置DisposableObj
以及何时(如果任何子代之后访问处置的对象),您可以辩称这应该导致异常-不要解决此问题,而应抛出异常,让异常冒泡,因此您可以在发现问题时修复逻辑。
在实现方面,您可以通过仅保留一个布尔值来实现此目的,该布尔值跟踪是否已处置DisposableObj
,并且在以后的访问中仅抛出ObjectDisposedException
。 为了澄清,我的意思是DisposableObj
对象本身应跟踪其状态,并在处理后对其进行任何方法调用时抛出ObjectDisposedException
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.