Is value type boxing when it is a field of reference type?
Asked Answered
A

6

6

There is code:

struct A
{
   int b;
}

class B
{
  A a;
  int b;
}

Questions are:

  1. Is a in B boxed or not?
  2. Is a in B located in stack or in heap?
  3. Is b in A boxed or not?
  4. Is b in A stack or in heap?
  5. Is b in B boxed or not?
  6. Is b in B stack or in heap?

I really don't understand It :(

Amass answered 5/10, 2011 at 8:34 Comment(5)
Why do you think any of those things are boxed?Candicecandid
This is a really old article, but it should help explain the differences... msdn.microsoft.com/en-us/magazine/cc301569.aspxFishmonger
This question would be about a million times easier to understand if you didn't have three things named "b" and two things named "a".Cigarillo
I suspect you have the false belief that "all value types are stored on the stack unless they are boxed, in which case they are stored on the heap". That belief is completely false. Lots of people have that false belief. The correct belief is that values are stored in storage locations, and storage locations are either short-lived or long-lived. If the analysis of a storage location shows that its lifetime is guaranteed to be short, that storage location goes on the stack or registers. Otherwise it goes on the heap.Cigarillo
Whether a storage location holds a reference or a value of value type is completely irrelevant to the analysis of its lifetime. Type of storage and lifetime of storage are completely separate concepts.Cigarillo
Q
8

1) No, there's no boxing here.

2) a will be on the heap, although that's an implementation detail

3) No, b in A isn't boxed

4) b in A will live wherever the containing A will live (so with a local variable of type A it'll usually be on the stack; with an instance variable of a class like B or any static variable, it'll be on the heap); again, this is an implementation detail

5) b in B isn't boxed either

6) b in B will be on the heap - again, an implementation detail

There's no boxing going on here as you haven't shown anything trying to use a value type value as a reference type value (e.g. object or an interface).

Again, the whole stack/heap distinction is an implementation detail. You should read Eric Lippert's blog posts on the topic.

Quadruped answered 5/10, 2011 at 8:38 Comment(2)
Hm, If I understand It right then value type CAN be stored in heap without being boxed? In such case fields of A inside B lie in the same place as fields of B itself. There is NO reference to A inside B?Amass
@Praetor12: It can be stored in the heap as part of another object (in this case an instance of A in B) or indeed part of another value type value which is already in the heap (in this case an int in A). There's no real concept of "reference to A".Quadruped
C
2

Using Google I found this:

Boxing and unboxing is a essential concept in C#’s type system. With Boxing and unboxing one can link between value-types and reference-types by allowing any value of a value-type to be converted to and from type object. Boxing and unboxing enables a unified view of the type system wherein a value of any type can ultimately be treated as an object. Converting a value type to reference type is called Boxing. Unboxing is an explicit operation.

Boxing is converting a value type to reference and that's not in you code. So answer to your "b-boxed" questions is "No".

Currier answered 5/10, 2011 at 8:38 Comment(0)
B
1
  1. The a member in B is not boxed.
  2. The a member in B is located on the heap. It's part of the object, and objects are always allocated on the heap.
  3. The b member in A is not boxed (but the A value may be boxed).
  4. The b member in A is part of A, so it's stored wherever the A value is stored, which can be either on the stack or on the heap.
  5. The b member in B is not boxed.
  6. The b member in B is on the heap, as part of the object.
Baugh answered 5/10, 2011 at 8:37 Comment(0)
D
0

Passing a value type by reference is not boxing either.

void SomeFunction(ref int a) a is not boxed.

int? value Nullable value types are also not boxed.

object my_box = my_integer my_value is a boxed version of my_integer

Value types contained in classes are not boxed (when would it be a value type if that was the case?)

Dolorisdolorita answered 5/10, 2011 at 8:57 Comment(0)
L
0

A storage location (variable, parameter, or field) of a structure type holds, within it, all of the fields--public and private--of that type. If the storage location is held on the stack as automatic variable or parameter, all of its fields will be likewise. If the storage location exists within a heap object, its fields will be within that same heap object.

Boxing works, internally, by defining for each value type a class type with the same name and members. When a value-type value is given to code which needs a class type, the system produces a new instance of the namesake class type and copies all the fields--public and private--from the value-type value to the the new object instance. Although the C# spec describes the boxed instance as being a value type, its behavior and internal workings will be those of a class type.

Lamonicalamont answered 26/2, 2012 at 21:3 Comment(0)
R
0

Having found this discussion very helpful, I've improved the original code and summarised it below:

struct StructA
{
    // Not boxed.
    // Live wherever the StructA value will live.
    // Stored on stack if StructA value is a local variable;
    // Stored on heap when StructA is a property in a class.
    int structB;
}

class ClassB
{
    // Not boxed.
    // Stored on the heap.
    // Struct can be stored on the heap as part of another object.
    StructA structA;

    // Not boxed.
    // Stored on the heap.
    int classBField;
}
Repeat answered 12/10, 2023 at 12:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.