.NET Forum / Languages / Managed C++ / February 2008
Can I have back my destructors, please?
|
|
Thread rating:  |
cctv.star@gmail.com - 21 Feb 2008 01:19 GMT In C++ you have RAII idiom that takes care of all your resources - memory, file handles, etc.
In C# you have GC that takes care of the memory, but it looks like you're completely on you own as far as other resources are concerned - just miss this Dispose() call and wait for all kind of interesting things to happen.
For every class that you consume the first thing you should note is whether it implements IDisposable or not, and handle it accordingly.
Now the problem: suppose you use some class, which does not implement IDisposable. All is well. And then, the maintainer of this class decides that he needs to use some other object, which does implement IDisposable, and to make this object a member. Although this should be just an implementation detail and completely private business, he has to make his own class implement IDisposable. And now your code still compiles fine, but is no longer correct, although the only thing that really has changed is just implementation of a class you use.
In a sense, whether some class implements IDisposable or not is just an implementation artifact for the author, but is indeed an interface change for the consumer.
Actually, I'm still learning C#, so I hope something of what I've written above is incorrect. Otherwise, please advise how to deal with the problem I've mentioned in practice (is there any way, at least, to make the consumer code uncompilable after such change?).
Cholo Lennon - 21 Feb 2008 02:19 GMT > In C++ you have RAII idiom that takes care of all your resources - > memory, file handles, etc. [quoted text clipped - 25 lines] > the problem I've mentioned in practice (is there any way, at least, to > make the consumer code uncompilable after such change?). Take a look to:
IDisposable, Finalizers, Destructors, and the Garbage Man http://www.eggheadcafe.com/articles/20050625.asp
The article shows how to implement IDisposable and Destructor (Finalizers) in a consistent way using C#. Also take a look to 'using' keyword to achieve RAII idiom. BTW I still prefer C++ memory management (with help of shared_ptr)
Regards
-- Cholo Lennon Bs.As. ARG
Carl Daniel [VC++ MVP] - 21 Feb 2008 02:42 GMT > In C++ you have RAII idiom that takes care of all your resources - > memory, file handles, etc. [quoted text clipped - 25 lines] > the problem I've mentioned in practice (is there any way, at least, to > make the consumer code uncompilable after such change?). Actually, you have all of this if you use managed C++ - you write your class with a destructor and the compiler takes care of calling Dispose at the right times.
Apparently, however, you wanted an answer for C#, but you posted in a C++ newsgroup - I'd suggest microsoft.public.dotnet.languages.csharp.
-cd
Tamas Demjen - 21 Feb 2008 20:22 GMT > Actually, you have all of this if you use managed C++ - you write your class > with a destructor and the compiler takes care of calling Dispose at the > right times. This is true for objects created with the stack syntax (C++/CLI) or the `using' statement (C#).
On the other hand, if you want to store resource objects in a container, that's not so convenient anymore. The standard collections (such as List<T>) don't automatically call Dispose on their items. Fortunately this is not that big of a problem, because it doesn't happen every day that you need to store a whole collection of resource handles.
There's one notable exception, though. If you use C++/CLI to wrap unmanaged classes, the wrappers automatically become resources, and Dispose should be called on them, especially if the wrapped unmanaged object allocates a lot of memory. And it is quite a reasonable expectation to store a bunch of those objects in a container.
It is not too hard to create your version of DisposingList<T>, based on List<T>, which automatically calls Dispose in its destructor, and in its Delete method too. Well, the container itself becomes a resource then.
I think it would be nice to have reference counted managed objects as an option (kind of like shared_ptr<>). However, it's difficult to find a real world situation when this is absolutely necessary.
There was a time when this bothered me a lot, but in reality GC is not bad in .NET. There're even weak references, kind of like weak_ptr in C++.
Also note that one can cause memory leaks even using shared_ptr in C++. It's enough to add objects into a container repeatedly, and never remove them, and it could grow indefinitely. So it's always possible to have a leak situation, even with reference counted smart pointers.
Tom
Carl Daniel [VC++ MVP] - 22 Feb 2008 06:13 GMT > There was a time when this bothered me a lot, but in reality GC is not > bad in .NET. There're even weak references, kind of like weak_ptr in > C++. It still bothers me a lot because GC is awful (or useless) when it comes to effective and efficient management of resources other than memory allocations - of which there are many in any program of substance. But, it's what we have.
-cd
David Wilkinson - 21 Feb 2008 10:44 GMT > In C++ you have RAII idiom that takes care of all your resources - > memory, file handles, etc. [quoted text clipped - 3 lines] > just miss this Dispose() call and wait for all kind of interesting > things to happen. [snip]
cctv:
This is a C++ group, so you are preaching to the choir here.
IMHO, the failure to implement RAII in a proper fashion in C# is a sad testament to how little input C++ had in the design of C#.
 Signature David Wilkinson Visual C++ MVP
Carl Daniel [VC++ MVP] - 21 Feb 2008 15:30 GMT > IMHO, the failure to implement RAII in a proper fashion in C# is a > sad testament to how little input C++ had in the design of C#. If I remember my C# lore correctly, it started life as a project known as Cool - which was initially undertaken by the C++ team.
-cd
David Wilkinson - 21 Feb 2008 16:50 GMT >> IMHO, the failure to implement RAII in a proper fashion in C# is a >> sad testament to how little input C++ had in the design of C#. > > If I remember my C# lore correctly, it started life as a project known as > Cool - which was initially undertaken by the C++ team. Carl:
That's interesting. I really don't know Java, but I had always believed that C# was more Java-like than C++-like.
I just don't see how anyone could think that the Dispose() pattern was superior to, or simpler than, RAII. For me RAII is one of the most elegant (and simple) features of C++.
 Signature David Wilkinson Visual C++ MVP
Carl Daniel [VC++ MVP] - 21 Feb 2008 17:09 GMT >>> IMHO, the failure to implement RAII in a proper fashion in C# is a >>> sad testament to how little input C++ had in the design of C#. [quoted text clipped - 6 lines] > That's interesting. I really don't know Java, but I had always > believed that C# was more Java-like than C++-like. It is - no doubt about it.
> I just don't see how anyone could think that the Dispose() pattern > was superior to, or simpler than, RAII. For me RAII is one of the > most elegant (and simple) features of C++. It's a mystery, indeed. I suspect that it was spurred by an easy to fall into but woefully incorrect conclusion that with GC you no longer need deterministic destruction. Java made the same mistake and has an even worse solution to the problem than C# (IDisposable but nothing like the 'using' statement in C#).
-cd
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|