Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

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

  • *Experts*
Posted

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

"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*
Posted

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

"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
Posted

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

  • *Experts*
Posted

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

"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
Posted

**********

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

  • *Experts*
Posted

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

"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

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...