Reputation: 14246
Suppose, I have following classes:
public class DisposableObj : IDisposable
{
public ChildObj CreateObj();
internal object GetSomething();
// ...
}
public class ChildObj
{
private DisposableObj m_provider;
public void DoSomething()
{
m_provider.GetSomething();
}
// ...
}
It's possible that at some point the disposable object will be disposed but child object will still have a reference to it.
If at this time user will call DoSomething
method then child object will try to access disposed object. This is not good hence the question:
How should I properly design such classes?
UPDATE/CLARIFICATION:
I am aware of ObjectDisposedException and all. My question probably should sound like: how to properly notify user about exceptional situation and how design the classes to make maintaining them easier?
Upvotes: 0
Views: 310
Reputation: 216293
First thougth that comes to mind:
Provide your ChildObj class with an internal boolean property called ProviderDisposed.
Set this property to true from Dispose in your DisposableObj
However you should keep a list of the objects created to comunicate to each one the disposed state of your main object.
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();
}
// ...
}
Upvotes: 2
Reputation: 160912
While that is a scenario that is technically possible, this should be an exceptional state in your progam - I can't imagine why you would deliberately set up for this scenario.
Having said, that make it clear in your design who is responsible to dispose DisposableObj
and when - if any child accesses the disposed object afterwards you can argue that this should cause an exception - don't work around this but throw an exception an let the exception bubble up so you can fix the logic when you discover the problem.
Implementation-wise you can achieve this by just keeping a boolean that keeps track of whether DisposableObj
is disposed and on a later access just throw ObjectDisposedException
. To clarify I mean the DisposableObj
object itself should keep track of its state and throw ObjectDisposedException
on any method call on it after it was disposed.
Upvotes: 2