Wentu Posted March 19, 2004 Posted March 19, 2004 Hi I am trying to understand the behaviour of boxing. here's the code, don't take into account the fact that is in a form: Dim A As Object = New Boolean Dim B As Object = New Boolean Dim mB As mioBool = New mioBool Dim C As mioBool = New mioBool Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load B = False mB.thisBool = False scegli(B) scegliBool(mB) End Sub Private Sub scegli(ByRef buleano As Object) A = buleano A = True End Sub Private Sub scegliBool(ByRef aMioBool As mioBool) C = aMioBool C.thisBool = True End Sub ************* when scegliBool is called, C points to the same object as mB, so when i change the boolean in C, also the boolean in mB changes. That's great. BUT, when i call scegli, i was expecting A to point to the same boxed boolean as B, and when i set A to TRUE, i thought B also would have changed to True, but this is not the case. Why ? how can i change the value of B acting only on the A object, how can i have B and A pointing to the same object and behaving in the same way ? Thankx Wentu Quote
*Experts* Nerseus Posted March 19, 2004 *Experts* Posted March 19, 2004 I'm guessing that mioBool is a class? When you assign a variable to a class you are only copying the pointer. As you saw, changing a property using either variable means you're changing the same data. When you do the assignment you ONLY copy the pointer - not the object itself. When you do an assignment on a struct or a value type (like bool, int, string, etc.) it makes a copy of the object. So B now points to a new version of the object. It doesn't matter if the values are boxed or not. The boxing only allows you to pass the bool to functions that take an "object" as a parameter. It also allows you to do things like call "ToString()" on an int. nerseus Quote "I want to stand as close to the edge as I can without going over. Out on the edge you see all the kinds of things you can't see from the center." - Kurt Vonnegut
*Experts* Nerseus Posted March 19, 2004 *Experts* Posted March 19, 2004 Whoops - forgot to answer the "big" question. Basically, you can't have two references to a value type. When you try and "point" a second variable to the object, boxed or not, you'll only get a copy. Now you *might* be able to do something if you allowed unmanaged code and created a pointer to your variable. I'm not sure if that's worth the effort though. Maybe if you explained what it was you were attempting to do, functionally, we could offer some help? -nerseus Quote "I want to stand as close to the edge as I can without going over. Out on the edge you see all the kinds of things you can't see from the center." - Kurt Vonnegut
Wentu Posted March 19, 2004 Author Posted March 19, 2004 Thanx Nerseus for ur answer. i am sorry i wrote in a cryptic way. What i imagined it happend was: A is an object, that is , a pointer to an object, but when i write dim A as Object = new boolean it points to enough memory for a boolean. The same is true for B. I pass to the function scegli the pointer B, and inside the function it is called in another way, who cares, it is always pointing to the same location of memory. When I write A = buleano i say: let A point to the same location where buleano points, that is, the same location where B is pointing (where i am storing a boolean). Now, i think the problem is here: if i write A = true i thought i was changing the value IN the memory location pointed by A, not the place where A is pointing. A is pointing where a boolean is stored, how can i change the boolean itself and not where A is pointing ?? Anyways... (and sorry for the awful crossposting): Here's what i was trying to do: I am working in NET CE and i have 2 forms, F (father) and S (son). F instantiates S and show it with ShowDialog(). In the constructor S i pass a boolean byRef, in S i can check or not a checkbox and depending on this check, i want the ByRef variable to change and be seen in F. So: In F: dim myBool as Object = new boolean dim newS as S(myBool) if myBool then doSomthing() else doSomethingElse() end if ----- in S private prBoolean as Object = new Boolean public sub new (ByRef aBool as Obj) prBoolean = aBool end sub Private Sub newS_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing If Me.myCombo.Checked = True Then prBoolean = False Else prBoolean = True End If End sub ---------------------------- now, when i set prBoolean = true , I was expecting that aBool and myBool all changed to True. I thought all of the 3 objects point to the same location and writing prBoolean = True changes the content of what is pointed, not the location to which prBoolean points. prBoolean is an Object, how do i tell to prBoolean to change NOT WHERE it's pointing but the boolean value it is keeping ?? thankx a lot again Quote
*Experts* Nerseus Posted March 19, 2004 *Experts* Posted March 19, 2004 As I said, bools are value types - any new "pointer" (variable) to a bool gets a copy. It doesn't matter if you box it, if you use ByRef, etc. The only place where you can change the original value is in the constructor, since that code has the ByRef argument. Assigning that to ANY other variable (boxed/unboxed/object/etc.) will get a COPY, not a pointer. You could solve this in 2 ways off the top of my head: 1. Have the child form S expose a bool value that form F reads. 2. Wrap your bool value in a class and pass the class to the constructor of S. For #1, you would change prBoolean in form S to be public. When you get control back in form F, you could reference form S's prBoolean variable to set the value of myBool. That puts the onus on form F to use the value that form S is giving you. For #2, you would create a new class that contains one bool property. Form F creates the class and passes it to form S. Form s saves that reference in its own variable. Then in form S, changing the bool value will change the underlying bool value. As a side note, the data in a class is always passed by reference. Only the pointer to the class is passed by value or by reference, based on the param type. Meaning, even if you changed your constructor to use ByVal for the class parameter, you could STILL change the bool value contained within it. To do #2, do something like this (this is C#, but you can follow): public class BoolData { public bool BoolValue; // Constructor takes a bool to default public BoolData(bool initValue) { BoolValue = initValue; } } // In Form F { .... private void CallFormS() { BoolData o = new BoolData(); FormS s = new FormS(true); s.ShowDialog(); // Right now, if s changed the bool value, it is changed here: // So o.BoolValue is whatever it was changed to on S } } // In Form S { private BoolData b; // constructor public FormS(BoolData initValue) { // b is a different pointer than initValue // but they both point to the same object. // So, changing b.BoolData will change initValue.BoolData b = initValue; // Change the value of b.BoolData to false Test(); } private void Test() { b.BoolData = false; } } -Nerseus Quote "I want to stand as close to the edge as I can without going over. Out on the edge you see all the kinds of things you can't see from the center." - Kurt Vonnegut
Wentu Posted March 19, 2004 Author Posted March 19, 2004 ********** You could solve this in 2 ways off the top of my head: 1. Have the child form S expose a bool value that form F reads. 2. Wrap your bool value in a class and pass the class to the constructor of S. ********** Thankx a Lot Nerseus Actually i was already using what u call Solution #2 but i though of it as a rather unelegant solution and trying to understand why my previous solution wasnt working. i think Solution1 is against incapsulation... Thankx for the explanations and suggestions! ;) Wentu Quote
*Experts* Nerseus Posted March 20, 2004 *Experts* Posted March 20, 2004 Solution #1 is very often used in conjunction with a modal popup. But whichever solution works best, that's what I'd go with :) -Nerseus Quote "I want to stand as close to the edge as I can without going over. Out on the edge you see all the kinds of things you can't see from the center." - Kurt Vonnegut
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.