S
Scott M.
Jonathan Wood said:Scott,
GC will optimize the heap, which prolongs running out of memory as long as
possible. I'm sorry, but you are mistaken if you think GC can prevent
running out of memory.
GC does more than optimize the heap, it "manages" the heap and makes
decisions about "when" and "if" objects need to be destroyed. To say that
the GC can't prevent us from running out of memory is incorrect. It most
certainly can and does.
I just got through describing that the very example you gave shows that we
not only need to know something about whether or not the class maintains
resources that must be cleaned up, but now we also need to know about
which classes might clean up other classes. I don't know how you define
encapsulation but to me it's about only needing to understand a class's
interface to use it, and not anything about it's implementation. That's
more than one clear example of how the lack of DF is a step in the other
direction.
And, I've said that we learn what we need to know from the interfaces of the
objects involved. We do not need to know how they do what they do. You
most certainly *can* call dispose on your Command object, but in the
scenario you've shown, it is unneccessary. I do not believe that having a
basic understanding of the nuances of a class so that I can use them more
effectively breaks encapsulation.
Again, I understand you may never agree to this but I've been doing this
long enough to understand the benefits of OOP and encapsulation. And,
here, learning this stuff is harder because I am not gaining all the
traditional benefits of OOP and encapsulation.
It's just my opinion. YMMV.
Ah, but I've been doing this long enough (from this side of the fence) to
understand the benefits of OOP in a managed environment. As a matter of
fact, I am a technology trainer and have been teaching .NET since its
inception. I have encountered many folks, just like yourself (comming to
..NET from a lower-level programming language like C/C++) and, over and over
seen that, for these folks, the switch to this managed framework can be
difficult due to the additional burdens the C/C++ environment places on
developers, but how used to it they get and how they are reluctant to give
it up as they move into .NET. There really much, in the way of OO benefits,
that you are losing here.
What if I had just told you to call dispose on any object that has such a
method and that this would be sufficient to cause the object to clean up
appropriately? That would put your whole argument about encapsulation to
rest, wouldn't it? Because if you choose to code by that rule, it will not
cause you *any* troubles in any situation you encounter, ever. You can code
this way, feel good about encapsulation and not feel that you've lost
anything. But, it just happens that a command object has a dispose method
because it inherits from the component class (which exposes such a method)
and that Microsoft puts a dispose method on the component class for the
benefit of the many subclasses in the framework that do *need* this
functionality. It just turns out that the command object doesn't. Now, you
know that encapsulation says the we do not *need* to know about an object's
implementation in order to use it and I still maintain that is true here. I
could have never mentioned anything about Dispose and your code would
function exactly as it needs to. But, you can't tell me that *if* I happen
to know something about an object's implementation, that I wouldn't be able
to write code for it in a more optmized way. That is not what encapsulation
says. I still maintain that we have full encapsulation here.
I really think that you should do a little more research on the GC, which
will show you that it does, in fact, protect us from memory leaks and
outages, which makes much of what you have been inquiring about (where to
use Try...Catch and creating "bullet-proof" non-crashable code), not an
issue in all but extreme coding scenarios or poorly designed hardware
architectures. There's no such thing as "bullet-proof" or "uncrashable"
code in any lanaguge. No, I can't make you that guarantee. But I can tell
you that for very nearly 100% of situations, running out of memory due to
simply instantiating an object won't or can't cause us to run out of memory.
In the extremely rare scenarios where it might, we'd most likely to
attribute the cause to either unmanaged resources not being properly used or
very poorly written managed code. But, hey, you can write bad code in any
language.
As for your original concern about persisting a copy of the data in a
DataSet, again I'll refer you to more research on the GC, the DataSet and
DataTable classes, and the overhead of keeping an active database "hook"
longer than is really needed.
-Scott