如何正确设计具有一次性对象内部引用的对象
本文关键字:对象 内部 引用 一次性 何正确 | 更新日期: 2023-09-27 18:28:11
假设,我有以下类:
public class DisposableObj : IDisposable
{
public ChildObj CreateObj();
internal object GetSomething();
// ...
}
public class ChildObj
{
private DisposableObj m_provider;
public void DoSomething()
{
m_provider.GetSomething();
}
// ...
}
有可能在某个时刻,一次性对象会被丢弃,但子对象仍然有对它的引用
若此时用户将调用DoSomething
方法,则子对象将尝试访问已处理的对象。这是不好的,因此问题:
我应该如何正确地设计这样的类?
更新/澄清:
我知道ObjectDisposedException等等。我的问题听起来可能应该是:如何正确地通知用户异常情况,以及如何设计类以使维护它们更容易?
虽然这在技术上是可能的,但在您的程序中,这应该是一种异常状态-我无法想象您为什么会故意设置这种情况。
话虽如此,这在设计中明确了谁负责处理DisposableObj
,以及何时-如果任何子对象随后访问了已处理的对象,您可以争辩说这应该导致异常-不要绕过这个问题,而是抛出一个异常,让异常冒出,这样您就可以在发现问题时修复逻辑。
在实现方面,您可以通过保持一个布尔值来实现这一点,该布尔值跟踪DisposableObj
是否被释放,并且在以后的访问中只抛出ObjectDisposedException
。为了澄清,我的意思是DisposableObj
对象本身应该跟踪它的状态,并在它被处理后在它的任何方法调用上抛出ObjectDisposedException
。
首先想到的是:
为ChildObj类提供一个名为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();
}
// ...
}