Unexpected Datatable Behaviour

Lotok

Well-known member
Joined
Jan 17, 2012
Messages
198
Location
Scotland
Programming Experience
5-10
I have an application where the initial form downloads a list of status's to a DataTable. That form then passes that DataTable byval over to other forms, which saves each form from accessing the same static data from the Database.

Example Status's,
Open, Closed, Awaiting Authorisation, Cancelled

One of the child forms needs to hide Closed and Awaiting Auth from a dropdownlist. They need to be there initially in case something is at that status, but once checked and given the all clear to do so, the application removes the unwanted 2.

After accessing a form which removes the 2 status's, it seems to be altering the mainforms DataTable, as if passed by reference. When passing the DataTable to another instance of the child form, the 2 options are not there.

I haven't posted a code sample I know, as I think I am probably missing some info on DataTables behavior and misusing it. If that is not the case, I will take the relevant code out to show you.

Many thanks for any help.
 
Hi,

I have been looking at this for about 10 minutes now and on the basis that I CAN easily replicate this issue, I am as confused as you are?? I agree with your comment that passing a value using ByVal should create a new instance of the passed object in the routine that is using it, so to still have a reference back to the original structure does not make any sense.

That aside, you can easily get round this by creating a copy of the DataTable and then passing that to your function / subroutine. i.e:-

VB.NET:
Dim myTableCopy As DataTable = myDT.Copy
Form2.RemoveUnwantedInfoAndShowResultInListBox(myTableCopy)

There is obviously an explanation to this but at this point I am still looking for answers.

I will post again in the future if I come across an explanation.

Hope that helps.

Cheers,

Ian
 
Good find and thanks for the syntax tip too.

The article comment

If you pass in a datatable ByVal with 10,000 rows, you don't expect, the
datatable to be copied, now having 20,000 rows in memory, do you?

is irritating, because actually YES. if i choose byval, that's pretty much what I expect as I probably having a reason for passing byval. Regardless though, I learnt something new today which is cool.

Very much appreciate your taking the time to help.
 
The value a reference type variable holds is a memory pointer to the object, when passing ByRef the same pointer is passed, when passing ByVal a copy of the pointer is passed. Neither copies the referenced object.
 
Yeah, I understand that, but I didn't think DataTable was a reference type, I thought structures and classes were value types.
Live and learn ;)
 
Hi JohnH,

Many thanks for the link. That is a much better explanation than what I found, and to be honest, I had no idea that a difference even existed in .NET as to how object types were treated when passed as parameters. Value Type vs Reference Type, that's a new one for me, but at least it clears up this point and expands my own knowledge at the same time. Thanks once again.

As Lotok says, you live and learn.

Cheers,

Ian
 
I had no idea that a difference even existed in .NET as to how object types were treated when passed as parameters.
That's because there is no difference. Parameters are treated exactly the same way whether they are a value type or reference type. When you pass a parameter by value then a copy of the variable contents is made and when you pass a parameter by reference a reference to the variable contents is made. That's it, that's all. The parameter passing mechanism cares not about the type of the variable. It simply makes a copy or a reference. The difference you see is purely as a result of the different behaviour of value types and reference types due to the fact that value type variables contain a value and reference type variables contain a reference.

Even if you don't understand the underlying mechanisms, the rules are very simple:

1. If you don't want to modify or replace the parameter value then pass by value.
2. If you want to replace the parameter value then pass by reference.
3. For reference types, if you want to modify the parameter then pass by value.
4. For value types, if you want to modify the parameter then pass by reference.
5. You cannot prevent a reference type parameter being modified, so if you don;t want the original object modified then you must explicitly create a copy.

In the above rules, "modify" means to set a field or property of the parameter and "replace" means to set the value of the parameter itself.
 
Friends, is this a good summary?

Value Types
Reference Types
ByVal
parameter variable holds a new value; it is forever detached from the source
parameter variable holds a new reference to the same object pointed by original variable; whatever is done to the underlying object will be reflected in both references, original and parameter
ByRef
parameter variable aliases the original variable that holds the value; whatever is done to parameter variable is done to original variable
parameter variable aliases the original variable that holds the original reference; whatever is done to parameter variable is done to original variable
 
Back
Top