This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Any sense to set obj = null(Nothing) in Dispose()?
I understand if this question is closed as a duplicate, but I'm having some trouble reconciling some posts on this topic.
First a little background. I have a class Foo as follows
public class Foo : IDisposable
{
private Dictionary<int, string> _reallyBigDictionary =
new Dictionary<int, string>();
public void Dispose()
{
_reallyBigDictionary = null;
}
}
Instances of Foo are known to have a limited scope (i.e. I know we're not keeping it around forever). Given it's instance's limited scope, I don't see how nulling out _reallyBigDictionary actually frees up memory sooner than the dispose. The way I understand it, these objects won't ever get cleaned up until garbage collection is run. At that time, references to the given instance of Foo will be null regardless, so I expect GC to reclaim that memory regardless.
These posts lead me to believe that there is no point in setting member variables to null:
Memory leak problems: dispose or not to dispose managed resources?
Is it better to destroy all objects or just let the garbage collector do the job?
This post makes me question otherwise:
Proper use of the IDisposable interface
Can anyone clarify this point for me? Is the IDisposable implementation really necessary here? Because I just can't convince myself it is.
You don't need IDisposable; here's why. In summary, you need to follow Rule 1: Don't implement IDisposable unless you need to.
There are only two situations when IDisposable does need to be implemented:
The class owns unmanaged resources.
The class owns managed (IDisposable) resources.
Since Dictionary<int, string> is not IDisposable, your class shouldn't be either.
By implementing the IDisposable interface you can scope the useage of resources with the Using statement.
Also many classes in the underying .NET Framework detect that a class is IDisposable and runs the Dispose() for you, absolving you of the responsibility of nulling your managed child objects.
EDIT ----
Because of comments and a markdown, I thought Id add to my answer :
Many many classes in the .NET Framework implement IDisposable - for example many Generic collection types. When you dispose of such a collection the Microsoft implementation will call your class's Dispose method, having detected that it implements IDisposable. Also, there is a case for setting a reference to an object to null genrally - including perhaps in your Dispose method. If you want to remove a reference to an object, set the reference to null. Other classes might want to maintain a reference to the same object, so the argument that setting a reference to null is wrong' is a flawed argument. Using your Dispose method to set the reference to null is no different than setting it to null in any other way - granted, but by doing it in your IDisposable implemnentation you can have a far more determinitic and error-proof way of ensuring that this happens. Implementing IDisposable is also an excellent way to implement scoping, e.g. for transactional algorithms etc. Implementaing IDisposable is usefull in many ways and neednt be avoided, as long as you know how and why it works. It always amazes me how few .NET developers truly understand the IDisposable interface, Finalizers, the garbage collector and .NET best practices in general
I don't think that disposal is necessary in this instance. It's not like it's an active connection that's going to stay open and keep using up resources. When you're done using it, it will manage itself.
If you really want to make sure that there are no memory leaks coming from that piece of code, you can try adding the following to the dispose method:
GC.Collect();
Related
NET for a long time now and have started to learn C#. One thing I suppose I may have asked years ago, got the answer but have completely forgotten it now as it is not something I implicitly use a lot is destructors. As I am going through learning C# I read an article about how to create these in C# however it has left me wondering. Let say I instantiate a class which has an object to another class.
Class C1
{
// Do something here
}
Class A
{
C1 objObjectToClass1 = new C1();
}
Class Main
{
A objObjectToClassA = new A();
}
and I make the object objObjectToClassA to null as I have been lead to believe that is the equivalent to object = nothing in VB.NET.
objObectToClassA = null;
Does this action also destroy objObjectToClass1?
Not as such, no. An object will be reclaimed by the garbage collector some time after it has become eligible for collection. This may be after you clear the last reference to it, but it could already be before if you never need the reference anymore after a certain point. But generally, setting a field where you store the instance to null will help the object becoming no longer reachable and getting reclaimed.
Generally you have no control over when objects are reclaimed by the GC. You can write finalizers which are methods that are called prior to reclaiming an object, but I'd very much not recommend it if you can help it. If you need a predictable way of causing an object to release any resources it might hold on to (what destructors in C++ often do), then implement the IDisposable interface:
class C1 : IDisposable {
public void Dispose() {
// Do cleanup here
}
}
This also enables you to use instances of that class in a using statement, which will call Dispose at the end of its block:
using (var c1 = new C1()) {
// do stuf with c1 here
} // at this point c1.Dispose() is automatically called
The garbage collector knows when there are no references any more to objects, and as far as I know, it even destroys objects that are only referenced by another.
That means that if you dereference objObjectToClassA (set it to null), that both objects will get destroyed, if there are no more references to either of the objects. Simply letting it go out of scope is enough too.
In effect, yes it will also destroy objectToClass1, but not immediately. In this case, setting the variable to null means that your application is no longer using that object, and hence it's eligible for garbage collection. Thinking about it simplistically (I'm sure the GC is smarter than this), once objectToClassA is collected then objectToClass1 is no longer referenced and will also be collected.
Joey's comments about IDisposable are definitely worth bearing in mind; try not to think in terms of finalisers for C# as you don't have control over when they run. Using IDisposable will give you the control that you need in order to tidy up resources.
Destroy is the wrong word, C# (as far as I know) does not have destructors in the C++ sense. No longer used objects are collected/"destroyed" by the garbage collector.
If no other reference to objObjectToClass1 is kept, objObjectToClass1 can also be collected if you set objObectToClassA to null
A question for you all.
In my company, we are developing an application that runs inside Microsoft’s MVC framework.
The controller classes that we are implementing inherit from the MVC base class Controller. Example:
public class MyController: Controller
{
protected bool IsDisposed { get; set; }
… various methods…
}
The discussion we are having in the team centers around the Dispose() pattern. Essentially, this involves implementing the IDisposable interface, preferably according to the Microsoft-endorsed pattern.
See for example this link: http://msdn.microsoft.com/en-us/library/fs2xkftw%28v=vs.110%29.aspx
Interestingly, our controller classes do not own any resources, either managed or managed. As a result, the implementation of Dispose(bool) is greatly simplified:
protected override void Dispose(bool disposing)
{
IsDisposed = true;
base.Dispose(disposing);
}
There is some disagreement about the use (or need) of the IsDisposed property, that is used in the following method:
protected void ThrowIfDisposed()
{
if (IsDisposed) throw new ObjectDisposedException(“MyController”);
}
This method is then called at the beginning of every method that does "real" work. The thinking here is that a disposed object should not be used again, hence it should throw the ObjectDisposedException. The other opinion is that, since Dispose(bool) does “nothing” (other than setting the IsDisposed property and calling Dispose(bool) on the base class), the “disposed” object is not really in a state that is unusable, so there is no reason to throw. Therefore, there is no reason to even implement Dispose(bool).
An argument against this is that MyController should throw when it is disposed and one of its methods is called, so that its behaviour does not change should in future versions managed and/or unmanaged resources be added.
The argument against this last point is that MyController should never add any resources in future versions, but rather it should be derived from should the need to add resources occur in the future. An additional question is: why doesn’t the (library) class Controller implement ThrowIfDisposed() or something similar?
So, summarizing, faction one wants to implement Dispose(bool) and ThrowIfDisposed() as shown above, faction two thinks they are unnecessary and wants to do away with them.
I see merits in both viewpoints, cannot really make up my mind. Opinions?
Interestingly, our controller classes do not own any resources, either managed or managed.
Then you do not need the IDisposable pattern.
This method [ ThrowIfDisposed() ] is then called at the beginning of every method that does “real” work.
The qustion here is: Why?
If you do want to track a usable/abandoned state then just don't call it IsDisposed.
why doesn’t the (library) class Controller implement ThrowIfDisposed() or something similar?
Because it isn't useful.
Go back to the beginning: why did somebody think this was necessary? What is it for?
It seems you can just rip it out.
If an object receives a request after being disposed, the request should not fail for any reason other than ObjectDisposedException--meaning it shouldn't cause a NullReferenceException, yield garbage data, crash the system, or do any other such thing. That does not imply that the request shouldn't succeed--merely that ObjectDisposedException should be the only mode of failure.
As for IsDisposed, I can't really see much use for it in most cases. Code which doesn't know whether an object is disposed generally won't know much else enough about the object's state to know whether it might be unusable for some other reason; consequently, code that doesn't know whether an object is disposed generally shouldn't do anything with it except--in some cases--to Dispose it, and in most of those cases where one would want to call Dispose on an object if it hadn't already been disposed, one should simply call Dispose unconditionally. There could be some value in having a method MayNeedDisposing which would return true for objects with non-trivial Dispose methods until they've been disposed, but such a method could unconditionally return false for objects with null Dispose methods [in cases where a class would e.g. register a callback purely for the purpose of calling Dispose on something, testing MayNeedDisposing beforehand could be a useful optimization].
Finally, with regard to whether a class or interface should implement or inherit IDisposable, the issue is not whether the type itself acquire resources, but rather whether the last surviving reference to something that does acquire resources may be stored in that type. For example, even though the vast majority of IEnumerator<T> implementations don't acquire resources, some do, and in many such cases the only references to such objects will be stored in variables of type IEnumerator<T>, held by code that has no idea whether the objects in question have any resources or not. Note that non-generic IEnumerator doesn't implement IDisposable but some implementations acquire resources. As a consequence, code which calls IEnumerable.GetEnumerator will be required to call Dispose on the returned enumerator if it implements IDisposable. The fact that IEnumerator doesn't inherit IDisposable doesn't absolve code which receives an IEnumerator implementation that also implements IDisposable from the responsibility of calling Dispose--it merely makes it harder for such code to carry out that responsibility.
Faction two is absolutely right. Don't do it.
Implementing IDisposable in the way described and for the reasons given is a violation of at least three good principles.
You ain't gonna need it. http://c2.com/cgi/wiki?YouArentGonnaNeedIt
Do the simplest thing that could possibly work. http://www.xprogramming.com/Practices/PracSimplest.html
Keep it simple stupid. https://en.wikipedia.org/wiki/KISS_principle
It's just wrong on every level. Don't do it.
Is there any guidance or best practices around who should call Dispose() on disposable objects when they have been passed into another object's methods or constuctor?
Here's a couple of examples as to what I mean.
IDisposable object is passed into a method (Should it dispose of it once its done?):
public void DoStuff(IDisposable disposableObj)
{
// Do something with disposableObj
CalculateSomething(disposableObj)
disposableObj.Dispose();
}
IDisposable object is passed into a method and a reference is kept (Should it dispose of it when MyClass is disposed?):
public class MyClass : IDisposable
{
private IDisposable _disposableObj = null;
public void DoStuff(IDisposable disposableObj)
{
_disposableObj = disposableObj;
}
public void Dispose()
{
_disposableObj.Dispose();
}
}
I'm currently thinking that in the first example the caller of DoStuff() should dispose of the object as it probably created the object. But in the second example it feels like MyClass should dispose of the object as it keeps a reference to it. The problem with this is that the calling class might not know MyClass has kept a reference and therefore might decide to dispose of the object before MyClass has finished using it.
Are there any standard rules for this sort of scenario? If there are, do they differ when the disposable object is being passed into a constructor?
P.S.: I have posted a new answer (containing a simple set of rules who should call Dispose, and how to design an API that deals with IDisposable objects). While the present answer contains valuable ideas, I have come to believe that its main suggestion often won't work in practice: Hiding away IDisposable objects in "coarser-grained" objects often means that those need to become IDisposable themselves; so one ends up where one started, and the problem remains.
Is there any guidance or best practices around who should call Dispose() on disposable objects when they have been passed into another object's methods or constuctor?
Short answer:
Yes, there is much advice on this topic, and the best that I know of is Eric Evans' concept of Aggregates in Domain-Driven Design. (Simply put, the core idea as applied to IDisposable is this: Encapsulate the IDisposable in a coarser-grained component such that it is not seen by the outside and is never passed to the component consumer.)
Moreover, the idea that the creator of an IDisposable object should also be in charge of disposing it is too restrictive and often won't work in practice.
The rest of my answer goes into more detail on both points, in the same order. I'll finish off my answer with a few pointers to further material that is related to the same topic.
Longer answer — What this question is all about in broader terms:
Advice on this topic is usually not specific to IDisposable. Whenever people talk about object lifetimes and ownership, they are referring to the very same issue (but in more general terms).
Why does this topic hardly ever arise in the .NET ecosystem? Because .NET's runtime environment (the CLR) performs automatic garbage collection, which does all the work for you: If you no longer need an object, you can simply forget about it and the garbage collector will eventually reclaim its memory.
Why, then, does the question come up with IDisposable objects? Because IDisposable is all about the explicit, deterministic control of a (often sparse or expensive) resource's lifetime: IDisposable objects are supposed to be released as soon as they are no longer needed — and the garbage collector's indeterminate guarantee ("I'll eventually reclaim the memory used by you!") simply isn't good enough.
Your question, re-phrased in the broader terms of object lifetime and ownership:
Which object O should be responsible for ending the lifetime of a (disposable) object D, which also gets passed to objects X,Y,Z?
Let's establish a few assumptions:
Calling D.Dispose() for an IDisposable object D basically ends its lifetime.
Logically, an object's lifetime can only be ended once. (Never mind for the moment that this stands in opposition to the IDisposable protocol, which explicitly permits multiple calls to Dispose.)
Therefore, for the sake of simplicity, exactly one object O should be responsible for disposing D. Let's call O the owner.
Now we get to the core of the issue: Neither the C# language, nor VB.NET provide a mechanism for enforcing ownership relationships between objects. So this turns into a design issue: All objects O,X,Y,Z that receive a reference to another object D must follow and adhere to a convention that regulates exactly who has ownership over D.
Simplify the problem with Aggregates!
The single best advice that I have found on this topic comes from Eric Evans' 2004 book, Domain-Driven Design. Let me cite from the book:
Say you were deleting a Person object from a database. Along with the person go a name, birth date, and a job description. But what about the address? There could be other people at the same address. If you delete the address, those Person objects will have references to a deleted object. If you leave it, you accumulate junk addresses in the database. Automatic garbage collection could eliminate the junk addresses, but that techncal fix, even if available in your database system, ignores a basic modeling issue. (p. 125)
See how this relates to your issue? The addresses from this example are the equivalent to your disposable objects, and the questions are the same: Who should delete them? Who "owns" them?
Evans goes on to suggest Aggregates as a solution to this design problem. From the book again:
An Aggregate is a cluster of associated objects that we treat as a unit for the purpose of data changes. Each Aggregate has a root and a boundary. The boundary defines what is inside the Aggregate. The root is a single, specific Entity contained in the Aggregate. The root is the only member of the Aggregate that outside objects are allowed to hold references to, although objects within the boundary may hold references to each other. (pp. 126-127)
The core message here is that you should restrict the passing-around of your IDisposable object to a strictly limited set ("aggregate") of other objects. Objects outside that aggregate boundary should never get a direct reference to your IDisposable. This greatly simplifies things, since you no longer need to worry whether the greatest part of all objects, namely those outside the aggregate, might Dispose your object. All you need to do is make sure that the objects inside the boundary all know who is responsible for disposing it. This should be an easy enough problem to solve, as you'd usually implement them together and take care to keep the aggregate boundaries reasonably "tight".
What about the suggestion that the creator of an IDisposable object should also dispose it?
This guideline sounds reasonable and there's an appealing symmetry to it, but just by itself, it often won't work in practice. Arguably it means the same as saying, "Never pass a reference to an IDisposable object to some other object", because as soon as you do that, you risk that the receiving object assumes its ownership and disposes it without your knowing.
Let's look at two prominent interface types from the .NET Base Class Library (BCL) that clearly violate this rule of thumb: IEnumerable<T> and IObservable<T>. Both are essentially factories that return IDisposable objects:
IEnumerator<T> IEnumerable<T>.GetEnumerator()
(Remember that IEnumerator<T> inherits from IDisposable.)
IDisposable IObservable<T>.Subscribe(IObserver<T> observer)
In both cases, the caller is expected to dispose the returned object. Arguably, our guideline simply doesn't make sense in the case of object factories... unless, perhaps, we require that the requester (not its immediate creator) of the IDisposable releases it.
Incidentally, this example also demonstrates the limits of the aggregate solution outlined above: Both IEnumerable<T> and IObservable<T> are way too general in nature to ever be part of an aggregate. Aggregates are usually very domain-specific.
Further resources and ideas:
In UML, "has a" relationships between objects can be modelled in two ways: As aggregation (empty diamond), or as composition (filled diamond). Composition differs from aggregation in that the contained/referred object's lifetime ends with that of the container/referrer. Your original question has implied aggregation ("transferable ownership"), while I've mostly steered towards solutions that use composition ("fixed ownership"). See the Wikipedia article on "Object composition".
Autofac (a .NET IoC container) solves this problem in two ways: either by communicating, using a so-called relationship type, Owned<T>, who acquires ownership over an IDisposable; or through the concept of units of work, called lifetime scopes in Autofac.
Regarding the latter, Nicholas Blumhardt, the creator of Autofac, has written "An Autofac Lifetime Primer", which includes a section "IDisposable and ownership". The whole article is an excellent treatise on ownership and lifetime issues in .NET. I recommend reading it, even to those not interested in Autofac.
In C++, the Resource Acquisition Is Initialization (RAII) idiom (in general) and smart pointer types (in particular) help the programmer get object lifetime and ownership issues right. Unfortunately, these are not transferrable to .NET, because .NET lacks C++'s elegant support for deterministic object destruction.
See also this answer to the question on Stack Overflow, "How to account for disparate implementation needs?", which (if I understand it correctly) follows a similar thought as my Aggregate-based answer: Building a coarse-grained component around the IDisposable such that it is completely contained (and hidden from the component consumer) within.
A general rule is that if you created (or acquired ownership of) the object then it is your responsibility to dispose it. This means that if you receive a disposable object as a parameter in a method or constructor you usually should not dispose it.
Note that some classes in the .NET framework do dispose objects that they received as parameters. For example disposing a StreamReader also disposes the underlying Stream.
This is a follow-up to my previous answer; see its initial remark to learn why I am posting another.
My previous answer got one thing right: Each IDisposable should have an exclusive "owner" who will be responsible for Dispose-ing of it exactly once. Managing IDisposable objects then becomes very comparable to managing memory in unmanaged code scenarios.
.NET's predecessor technology, the Component Object Model (COM), used the following protocol for memory management responsibilities between objects:
"In-parameters must be allocated and freed by the caller.
"Out-parameters must be allocated by the called; they are freed by the caller […].
"In-out-parameters are initially allocated by the caller, and then freed and reallocated by the one called, if necessary. As is true for out parameters, the caller is responsible for freeing the final returned value."
(There are additional rules for error cases; see the page linked to above for details.)
If we were to adapt these guidelines for IDisposable, we could lay down the following…
Rules regarding IDisposable ownership:
When an IDisposable is passed into a method via a regular parameter, there is no transfer of ownership. The called method can use the IDisposable, but must not Dispose it (nor pass on ownership; see rule 4 below).
When an IDisposable is returned from a method via an out parameter or the return value, then ownership is transferred from the method to its caller. The caller will have to Dispose it (or pass on ownership over the IDisposable in the same way).
When an IDisposable is given to a method via a ref parameter, then ownership over it is transferred to that method. The method should copy the IDisposable into a local variable or object field and then set the ref parameter to null.
One possibly important rule follows from the above:
If you don't have ownership, you must not pass it on. That means, if you received an IDisposable object via a regular parameter, don't put the same object into a ref IDisposable parameter, nor expose it via a return value or out parameter.
Example:
sealed class LineReader : IDisposable
{
public static LineReader Create(Stream stream)
{
return new LineReader(stream, ownsStream: false);
}
public static LineReader Create<TStream>(ref TStream stream) where TStream : Stream
{
try { return new LineReader(stream, ownsStream: true); }
finally { stream = null; }
}
private LineReader(Stream stream, bool ownsStream)
{
this.stream = stream;
this.ownsStream = ownsStream;
}
private Stream stream; // note: must not be exposed via property, because of rule (2)
private bool ownsStream;
public void Dispose()
{
if (ownsStream)
{
stream?.Dispose();
}
}
public bool TryReadLine(out string line)
{
throw new NotImplementedException(); // read one text line from `stream`
}
}
This class has two static factory methods and thereby lets its client choose whether it wants to keep or pass on ownership:
One accepts a Stream object via a regular parameter. This signals to the caller that ownership will not be taken over. Thus the caller needs to Dispose:
using (var stream = File.OpenRead("Foo.txt"))
using (var reader = LineReader.Create(stream))
{
string line;
while (reader.TryReadLine(out line))
{
Console.WriteLine(line);
}
}
One that accepts a Stream object via a ref parameter. This signals to the caller that ownership will be transferred, so the caller does not need to Dispose:
var stream = File.OpenRead("Foo.txt");
using (var reader = LineReader.Create(ref stream))
{
string line;
while (reader.TryReadLine(out line))
{
Console.WriteLine(line);
}
}
Interestingly, if stream were declared as a using variable: using (var stream = …), compilation would fail because using variables cannot be passed as ref parameters, so the C# compiler helps enforce our rules in this specific case.
Finally, note that File.OpenRead is an example for a method that returns a IDisposable object (namely, a Stream) via the return value, so ownership over the returned stream is transferred to the caller.
Disadvantage:
The main disadvantage to this pattern is that AFAIK, noone uses it (yet). So if you interact with any API that doesn't follow the above rules (for example, the .NET Framework Base Class Library) you still need to read the documentation to find out who has to call Dispose on IDisposable objects.
In general, once you're dealing with a Disposable object, you're no longer in the ideal world of managed code where lifetime ownership is a moot point. Resultantly, you need to consider what object logically "owns", or is responsible for the lifetime of, your disposable object.
Generally, in the case of a disposable object that is just passed into a method, I would say no, the method should not dispose the object because it's very rare for one object to assume ownership of another object and then be done with it in the same method. The caller should be responsible for disposal in those cases.
There is no automatic answer that says "Yes, always dispose" or "No, never dispose" when talking about member data. Rather, you need to think about the objects in each specific case and ask yourself, "Is this object responsible for the lifetime of the disposable object?"
The rule of thumb is that the object responsible for creating a disposable owns it, and thus is responsible for disposing it later. This doesn't hold if there's an ownership transfer. For example:
public class Foo
{
public MyClass BuildClass()
{
var dispObj = new DisposableObj();
var retVal = new MyClass(dispObj);
return retVal;
}
}
Foo is clearly responsible for creating dispObj, but it's passing the ownership to the instance of MyClass.
One thing I decided to do before I knew much about .NET programming, but it still seems a good idea, is have a constructor that accepts an IDisposable also accept a Boolean which says whether ownership of the object is going to be transferred as well. For objects which can exist entirely within the scope of using statements, this generally won't be too important (since the outer object will be disposed within the scope of the Inner object's Using block, there's no need for the outer object to dispose the inner one; indeed, it may be necessary that it not do so). Such semantics can become essential, however, when the outer object will be passed as an interface or base class to code which doesn't know of the inner object's existence. In that case, the inner object is supposed to live until the outer object is destroyed, and thing that knows the inner object is supposed to die when the outer object does is the outer object itself, so the outer object has to be able to destroy the inner one.
Since then, I've had a couple of additional ideas, but haven't tried them. I'd be curious what other people think:
A reference-counting wrapper for an IDisposable object. I haven't really figured out the most natural pattern for doing this, but if an object uses reference counting with Interlocked increment/decrement, and if (1) all code that manipulates the object uses it correctly, and (2) no cyclic references are created using the object, I would expect that it should be possible to have a shared IDisposable object which gets destroyed when the last usage goes bye-bye. Probably what should happen would be that the public class should be a wrapper for a private reference-counted class, and it should support a constructor or factory method which will create a new wrapper for the same base instance (bumping the instance's reference count by one). Or, if the class needs to be cleaned up even when wrappers are abandoned, and if the class has some periodic polling routine, the class could keep a list of WeakReferences to its wrappers and check to ensure that at least some of them still exist.
Have the constructor for an IDisposable object accept a delegate which it will call the first time the object is disposed (an IDisposable object should use Interlocked.Exchange on the isDisposed flag to ensure it's disposed exactly once). That delegate could then take care of disposing any nested objects (possibly with a check to see if anyone else still held them).
Does either of those seem like a good pattern?
I am currently working on fixing a c# codebase which does not have a good pattern of Dispose usage.
It is a large codebase, it is a resource demanding codebase and it uses many custom unmanaged c++ libraries at the low level.
I have a good understanding of the dispose pattern. I have spent some time understanding what I believe to be the gold standard article on the issue: Joe Duffy's dispose article
In an attempt to minimise code duplication, we have been considering some dispose helper classes, and so my question:
If a base class implements a standard Dispose pattern should it allow its disposed flag to be shared ie. marked as protected?
To clarify I mean should there only be a single boolean state within an inheritance heirarchy that defines whether an object instance has been disposed or should there be a private boolean at each step of the inheritance ladder?
The examples in MSDN and at the above link set a flag at each level, but never explain the reasoning behind it. I am in two minds on the issue, what are your thoughts and reasons?
I would say no it should not share the flag. Sharing the flag creates opportunities for failure which better encapsulation could prevent.
For instance, consider the scenario where you have a readonly Disposed property on the base most class. The backing field is only set to true in the Dispose(disposing) method on the base class. This means that the property Disposed can only ever return true if the base class Dispose is called (barring evil reflection of course). This allows the base class to provide an enforceable contract.
Now consider the opposite, where there is a protected setter. Any class can now arbitrarily set the Disposed property to true without disposing anything. This creates an opportunity for Dispose to return true when nothing is disposed.
I would choose the first option because it provides the most enforceable contract.
I would recommend having a Disposed property on the base class with a public getter and a protected setter.
In the case you have methods that should do something different when the class has been disposed, for example throwing an exception, I would create a protected only getter property for the base class that reads the private field on the base class. This way you allow any inheritor to know if he's able to perform an operation.
Then, for knowing if a class has already been disposed into its own dispose method (for example: to avoid releasing resources twice), I think that having a private flag is better for clarity and maintenance.
In addition to JaredPar's answer, I'd add that it is not always necessary for there to be a _disposed flag. Very often, the other "resource-related" fields of the object naturally provide a way to represent the disposed state.
For example, an external COM object that needs to be Shutdown before it is discarded would be represented by a reference to the COM object, and so the relevant part of Dispose would be:
if (_comObject != null)
{
_comObject.Shutdown();
_comObject = null;
}
This can safely be run multiple times without calling Shutdown more than once, as is required. Other methods that attempt to use _comObject after Dispose will get a NullReferenceException, or ideally those methods would check the _comObject field and throw ObjectDisposedException.
I find this is more often true than not - having frequently implemented IDisposable, I can't recall ever needing a separate _disposed field. Introducing one would increase the degrees of freedom (increase the number of ways for me to screw it up).
So this is unlikely to be that useful for derived classes even if it was a safe idea (which it isn't, as JaredPar explains).
HOW do i know when i need to dispose of something? Someone just mention i had several objects in my code that i need to dispose of. I had no idea i needed to dispose anything (this is my first week with C#). How do i know when i need to dispose an object? i was using http://msdn.microsoft.com/en-us/library/system.security.cryptography.hashalgorithm.aspx and i do not see any mention of dispose on the page or seen it mention in any other objs i was told i to dispose (by someone on SO).
I know i need to when something inherits IDisposable but HOW do i KNOW when it does inherit it?
Similar questions here:
When should I dispose my objects in .NET?
When should I manually dispose of controls? How do I know if a control implements IDisposable?
How to dispose a class in .NET?
Will the GC call IDisposable.Dispose for me?
Identify IDisposable objects
You should dispose anything that implements IDisposable. Just wrap it on an using:
using(var some = new Something())
{
//use normally
}
An easy way would be to type obj.disp and see if intellisense has a dispose method.
The class implements the interface IDisposable, that means that it has a Dispose method.
Not every class that implements IDisposable requires you to call Dispose, but most of them do. If you see that the class implements IDisposable (or has a Dispose method because it inherits the interface from a base class), you have two choises:
Dig deep in the documentation to find out why the class implements IDisposable, and if you really need to call Dispose.
Just call Dispose.
Either method is safe. If the Dispose method doesn't do anything, the call will be very quick. You can even call Dispose more than once without harm.
Even better then just calling the Dispose method is to use a using block:
using (FileStream s = File.OpenRead(path)) {
...
}
At the end bracket of the block the Dispose method is called automatically. The using block is implemented as a try...finally, so the Dispose method is guaranteed to be called even if an exception occurs in the block.
If an class implements IDisposable you should dispose of intances of that class. If it doesn't you don't. In this case HashAlgorithm derives from ICryptoTransform which derives from IDisposable. This means all instance of classes descending from HashAlgorithm must be disposed.
You should dispose of any object that implements the IDisposable interface.
public abstract class HashAlgorithm : ICryptoTransform,
IDisposable
Anything that has unmanaged resources (DB connections for example) should implement the IDisposable interface.
There are a couple of good reasons for this:
You know that the unmanaged resources (which are typically quite scarce) are going to be cleaned up. Usually these will be cleared up in the finalizer anyway, but due to how the GC has to tidy up objects with finalizers this could take a while.
If you implement the standard dispose pattern you save the GC a lot of work as it doesn't need to call the finalizer.
I know i need to when something
inherits IDisposable but HOW do i KNOW
when it does inherit it?
Assuming you're using Visual Studio. I usually right click on the type, then "Go To Definition". If I see that it, or any of its super classes, implement IDisposable, I make sure I call Dispose on it. This is typically done by wrapping it in a using block as others have mentioned.
"Will the last person to leave the room please turn out the lights?"
An object which implements IDisposable holds the information and impetus necessary to do some "clean-up" operations that should happen "sometime", but which can't happen while the object is still in use. If the object is totally abandoned, those clean-up operations won't happen. The system includes a custodian, with which objects can register when they are created; if an object is abandoned by absolutely everyone but the custodian, the custodian can ask the object to perform its cleanup actions before the custodian too abandons it. Note that for a variety of reasons, the custodian isn't 100% effective at handling abandoned objects. It is thus very desirable that, whenever possible, the last entity to hold a useful reference to an object dispose of it before abandoning the reference.