You see. This is the whining bullshit that I'm talking about. And I didn't even say anything in this thread.
Here's another tome I was compelled to write, but that I won't be posting.
John.
--
Ryan Heath wrote:
> Lets put the record straight for all the .net programmers out there
> (and for ourselfs)
OK: IDisposable is broken.
> - There is no diff between Close and Dispose (if implemented correctly)
Incorrect.
> other than that after a Dispose, the object is not usable for other actions
That's one difference. What about the fact that Dispose is optional and Close is probably not? What about that Dispose can be called any number of times but Close probably not? What about that Dispose can't throw exceptions (the stupidest thing I ever heard of; what if there's an exception?) but Close probably can?
> - use (whenever appropriate)
What constitutes appropriate? This is like telling someone 'obey the law' and then not telling them what the law is.
> - don't use Dispose/Close when you do not control the objects lifetime
What is 'Close'? You mean Stream.Close()? SqlConnection.Close()? Door.Close()?
Close is a 'word'. It doesn't mean anything to this discussion without specific context. I assume when you say Dispose you mean IDisposable.Dispose, which is definitely different to SqlConnection.Close() which in turn is different to Stream.Close() and almost certainly different to Door.Close().
> I think thats about it...
If only that were so.
> Anyone more suggestions to add to this list?
- IDisposable is an interface with a single method, Dispose, that you can *optionally* call when you are finished with an object to affect immediate release of its unmanaged resources. If you don't call Dispose then these unmanaged resources will be released in a finaliser.
- Close is the name of a method that you will find on many interfaces, typically with a matching Open() method. A common pattern is that if you call Open() once you must guarantee to call Close() once.
- Doing more in IDisposable.Dispose than releasing unmanaged resources and invalidating the instance undermines the usefulness of the interface, because developers can not be sure of how to treat it when there is a question mark over ownership or scope. Developers who come to rely on the 'extended' contract may have a problem in the future. Developers who are forced to rely on the 'extended' contract will be furious.
- Having 'using' target the IDisposable undermines its usefulness as a C# language integration feature for use as a scoping tool. Because in order to maintain the integrity of the IDisposable interface nothing other than the release of unmanaged resources should be done with it. Thus making 'using' useless in a purely managed environment.
- IDisposable is tightly integrated to the .NET component model, forcing tight ownership.
- IComponent defines a Disposed event that seems to somehow be related to the optional IDisposable.Dispose method.
- Sometimes specs claim 'Dispose' is called but IDisposable.Dispose isn't called. For example, there are situations where ControlCollection.Dispose() is called directly rather than IDisposable.Dispose(). ControlCollection.Dispose() and IDisposable.Dispose() on ControlCollection are not the same thing! If ControlCollection.Dispose does the same thing as the IDisposable.Dispose method on ControlCollection then if ControlCollection is not sealed then it should be implemented like this:
public class ControlCollection : ..., IDisposable {
void IDisposable.Dispose() {
// release unmanaged resources
// suppress finalization
}
~ControlCollection() {
// release unmanaged resources
}
public void Dispose() {
((IDisposable)this).Dispose();
}
}
- Interfaces should be implemented *on the interface* for all but sealed classes.
- IDisposable started life as a hack for deterministic finalisation but tried to grow in its scope, and failed.
- IComponent declares IDisposable even though many IComponent objects do not own unmanaged resources.
- Some classes in the BCL implement IDisposable.Dispose but do more than release unmanaged resources. As a result you have to question whether you should or should not be calling Dispose on any given instance.
- IDisposable is only suitable or useful for strong ownership situations. The entire point of the GC is that you don't need to worry about strong ownership. That is, IDisposable goes a long way to undermining the facility in GC, particularly because of its poor specification and implementation. You really can't expect anyone to call Dispose in a managed environment where 'sharing resources' is supposed to be trouble free.
- IDisposable sucks and blows at the same time!
John.
It's amusing and sad that all the people who really understand IDisposable are so sick of arguing with people about it that they, by now, mostly ignore questions about it. Thus people end up with really over-simplified, useless summaries and/or "guidelines".
http://discuss.develop.com/archives/wa.exe?A2=ind0410a&L=dotnet-clr&T=0&F=&S=&P=7025
It would be nice if, when people really don't know what they're talking about, they would not argue with people who have a clue. It only serves to perpetuate ignorance, really.
I guess so. I think arguing with people is a good way to learn things. Putting questions in the form of assertions makes it easier for people to address them.
I don't really have a problem with it.
What is a real shame is that MS has botched this aspect of their framework so seriously that they can't come out and help people understand it, because doing so would be such bad PR.
So we chow down on bullshit, because they botched it.
They could fix it you know. The truth is that most of this stuff is there so that the framework can get back 'unmanaged resources'.
In case you haven't realised yet, 'unmanaged resources' is mostly just the code name for 'Win32 resources'. In other words "the stuff that if leaked will make the entire operation system perform like a peice of shit, and we don't want to let some gumby VB programmer fuck up our customer's operating system and give us a bad name, so we'll just try and make sure no matter how bad they fuck it up that we can recover *our system resources*, and if the developers crappy app leaks like a seive (and it will) that won't be our problem."
Thus IComponent is IDisposable and there is strong ownership. Because MS would sooner have your app crash than allow you to leak like a bitch and make their system look like a joke as a result.
And they didn't do a real good job themselves either.
Bah.
Btw, I'm a big fan of Ryan. He's a top bloke. I'd never say a bad word about him. He sent me a release of a charting component that he's working on. Very nice bloke indeed! :)
I do think that he's only trying to come up with a set of workable rules. The problem is that it's mostly futile..
John.
Yeah, I agree with your analysis.
Also, I don't have a problem with Ryan, either. I feel sorry for him in this particular area because he's getting a slanted (read "incorrect") view on the whole IDisposable issue, which could result in him making faulty assumptions and ultimately bad coding decisions.
Plus, I'd think he's even cooler if he gave *me* some free stuff. ;)
--Stuart
Well then, you should send him a private email and tell him where the answers to his questions are, and ask him if he'd be happy to show you his charting component! :)
John.
Well, I'm glad you set him straight off-list, at least. For a second there I was afraid you'd given up on your Quest To Save The World. :)
--Stuart
Actually, I haven't done that yet, although I was planning to do so (eventually). I was just kicking it to see if anything else interesting was going to happen on list first..
My comment above was an invitation for you to tell him for me ( not that you'd need my blessing or anything.. :P ). I'll give you another hour, or else I'll send him the email. At which point you might lose your opportunity to ask for the charting component! :)
John.
p.s. The read lock I issue with this message is implicitly bounded for eternity to be relevant to the period of time 2004-10-04-192823 UTC to 2004-10-04-202823 UTC. Thereafter its relevance is limited to history. ;)