Best Practices Questions - Sending objects to/from a class modules/functions, etc?

C

Chuck Ritzke

I keep asking myself this question as I write class modules. What's the
best/smartest/most efficient way to send a large object back and forth to a
class module?

For example, say I have a data access module that creates a large
disconnected dataset from a database. I want to pass that dataset back to
the calling program. And then perhaps I want to send that dataset to another
class module.

At first it seems that the "object oriented" approach would be to create a
dataset property in each class module, then run a method that creates the
dataset, and then read the property from the calling program. (and visa
versa if I want to send a dataset to another class module).

Now admittedly, I am not sure I understand how memory is used, garbage
cleanup issues, etc., but this seems inefficient. Won't a separate copy of
the dataset then exist in memory in each of the class modules and the
calling program until the class objects get disposed of?

It seems to me that it would be more efficent to pass a dataset (or any
large object) ByRef to each class as an argument in the method. For example
in the calling program...

Dim MyDataSet as New DataSet
MyObject.MyMethod(MyDataSet)
'Do stuff
MyDataSet=Nothing

and then in the class...

Public Sub MyMethod (ByRef MyDataSet as DataSet)
'Create or use MyDataSet
End Sub

....so that only one copy of the dataset exists at any point in time. Am I
thinking about this correctly?


In a similar vein, it seems convenient sometimes to write Function Subs that
return an object. But then I wonder whether I have cleanup problems because
you can't dispose of the object inside the Function that creates it, if you
need to return the object. I can dispose of the returned object when I'm
done with it, but do I have a problem with a copy of an object remaining
inside the Function Sub? If so, it seems again that I should pass the
dataset as a ByRef argument.

While on the subject of cleaning up. Can someone explain when/if you need to
use the Dispose method for objects that have them? Again with my dataset,
when I am done with it, is there any advantage to...

MyDataSet.Dispose()
MyDataSet=Nothing

I guess I don't understand what Dispose does that Nothing doesn't already
do.

Thanks in advance,
Chuck



Can anybody set me straight here?

Thanks,
Chuck
 
W

William Ryan eMVP

Hi Chuck:
Chuck Ritzke said:
I keep asking myself this question as I write class modules. What's the
best/smartest/most efficient way to send a large object back and forth to a
class module?

It really depends.. read on.
For example, say I have a data access module that creates a large
disconnected dataset from a database. I want to pass that dataset back to
the calling program. And then perhaps I want to send that dataset to another
class module.

At first it seems that the "object oriented" approach would be to create a
dataset property in each class module, then run a method that creates the
dataset, and then read the property from the calling program. (and visa
versa if I want to send a dataset to another class module).

This isn't necessarily so. There is a distinction between instance methods
and shard methods. For instance, you can call MessageBox.Show("Blah")
without instantiating an instance of a messagebox. There's nothing unOOP
about this. Many other classes behave similarly and if you look at the File
class it has an instance version FileInfo. In this instance, you may want
to create either a singleton class or similar implementation, or just make
the dataset a Shared (in VB.NET ) or static (in C#) property. Then you
don't need to instantiate an object at all to hold it and it can be
rerferenced from anywhere. Shared/Static properties exist as roots (ignore
that for now, it needs a lot of qualification and if you don't understand
Garbage Collection i'll just confuse you)so they are handled differently
from other objects
Now admittedly, I am not sure I understand how memory is used, garbage
cleanup issues, etc., but this seems inefficient. Won't a separate copy of
the dataset then exist in memory in each of the class modules and the
calling program until the class objects get disposed of?
It's really worth reading up on. Memory management is much different in
..NET than other environments, and it's really something you need to know
about
It seems to me that it would be more efficent to pass a dataset (or any
large object) ByRef to each class as an argument in the method. For example
in the calling program...

I think you are confusing passing By Ref/By Val w2ith Value Types and
Reference Types. Two totally different issues. Passing a Reference Type by
Val passes a reference to it, you aren't passing a copy. DataSets are
Reference Types, so you gain nothing by passing them by Reference (and in
almost every instance, you'll want to avoid this).

Just as a test, create a method that takes a DataTable as a Parameter. In
the first case, fill your datatable so it has rows, then pass it to your
function. IN your function, call datatable.Clear (maybe it's Rows.Clear)
but you want to clear all of the rows. Pass it in ByVal. The next line
after the call to the function, use
MessageBox.Show(MyDataTable.Rows.Count.ToString()); //Make sure it had
rows before so you see the distinction. You'll get 0 as the value.

Passing a Reference Type by Val passes a reference to the object, so
whatever you do to it is done to the actual object. This is a critical
point here and it's not the same as VB6 or old VC++ where passing it by Val
passed a Copy. The type (reference vs. value) is critical here and passing
a reference type byVal will yield Totally different results than passing a
Value type by val.
Dim MyDataSet as New DataSet
MyObject.MyMethod(MyDataSet)
'Do stuff
MyDataSet=Nothing

and then in the class...

Public Sub MyMethod (ByRef MyDataSet as DataSet)
'Create or use MyDataSet
End Sub

...so that only one copy of the dataset exists at any point in time. Am I
thinking about this correctly?

I think in this instace, creating it as a Shared Property (since you appear
to be using VB.NET) will solve your problem. You can then reference it from
anywhere and you will only need to reference the shared property. You won't
even need to instantiate a class. You may also want to create it as a
singleton object (google on Singleton VB.NET to get an implementation if you
want to ensure that you only ever have one instance.
In a similar vein, it seems convenient sometimes to write Function Subs that
return an object. But then I wonder whether I have cleanup problems because
you can't dispose of the object inside the Function that creates it, if you
need to return the object. I can dispose of the returned object when I'm
done with it, but do I have a problem with a copy of an object remaining
inside the Function Sub? If so, it seems again that I should pass the
dataset as a ByRef argument.

Once again, DataSets are reference types
While on the subject of cleaning up. Can someone explain when/if you need to
use the Dispose method for objects that have them? Again with my dataset,
when I am done with it, is there any advantage to...

In general, you don't need to call dispose on managed resource. Calling
dispose doesn't mean it's dead. It's only dead after it's been garbage
collected and unless you call GC Manually (which should be avoided unless
you Really know what you are doing and darned sure you want to do this) then
you don't know when or if GC will happen.
MyDataSet.Dispose()
MyDataSet=Nothing

I guess I don't understand what Dispose does that Nothing doesn't already
do.

In this instance, not much. Dispose can do a bunch of cleanup so it depends
on the object's implementation. You can define IDisposable in your own
objects (whether you should and when is another subject). Technically,
Dispose could create 50 new objects although that would be silly. Setting
it to nothing means there are no strong references to it anymore and if you
try, you'll get a null reference exception.

You are asking a lot of good questions, but while I can give you a cursory
answer to them, this isn't a trivial subject. Entire chapters of books and
numerous articles are written on the subject.... Jeffery Richter has a bunch
of great articles on MSDN about it. It'd probably be best if you looked
them over first.

check out Reference Type vs. Value Type
WeakReference
GarbageCollection
IDisposable, Finalize Pattern
MSDn has a ton of articles on this,

http://www.programming-x.com/programming/msdn-magazine.html
http://msdn.microsoft.com/msdnmag/issues/1200/GCI2/default.aspx
http://www.aleksys.com/aleksys/BookDetail.cfm/BookID=109638/BookSubject_ID=7099
 
C

Chuck Ritzke

Thanks very much Bill for the detailed response. That definitely points out
some misconceptions I had and points me to some things to look

Thanks again,
Chuck
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top