5

I have:

A struct

struct Data { int a; int b; }

A class containing the struct

class Packet {
    Data DataStruct;
}

When I now instantiate my class, I assume that the struct lives on the heap. If I now do something like

SomeClass.Process(new Packet().DataStruct);
SomeClass.Process(new Packet().DataStruct.a);

will it be passed as value?

If not, is there any reason not to make the struct into a class instead?

1
  • 1
    Here's the trick: just forget about the heap and the stack. Reference types as treated as references, value types are treated as values. That's it. Commented Feb 16, 2011 at 10:08

3 Answers 3

3

structs are value types, so it will be passed as value. Classes are reference types.

Everything will be passed as value unless out or ref is specified.

Sign up to request clarification or add additional context in comments.

2 Comments

A class reference is passed by value, unless it's an out or ref, when the reference is passed by reference.
I see. So, if I have stuff like: c = new C(); a = c; the reference to c gets copied into a? While b = new Struct(); a = b I actually copy the data itself.
1

A struct is always passed by value. In other words, a copy of it is created and provided to the called function.

While the struct is allocated on the heap, its actually part of the class its contained by rather than as a separate entity.

1 Comment

To be more precise, everything is passed by value unless the parameter has the ref or out modifier. (In the case of reference types, the reference is also passed by value)
1

The fact that an instance of a struct lives on the heap or the stack is not relevant at all. It's nice to know that it will live on the heap on Microsoft's implementation of the CLR, but that's about it. It's just an implementation detail.

Value types (structs) always have value semantics. This is not the same as saying that they pass-by-value, because it is relevant even when there are no method calls:

struct Data { public int a; public int b; } // Don't do this at home
var x = new Data { a = 1, b = 42 }; // x.a == 1, x.b == 42
var y = x; // x.a == 1, x.b == 42, y.a == 1, y.b == 42
y.a = 2; // x.a == 1, y.a == 2
var z = y; // x.a == 1, y.a == 2, z.a == 2
z.a = 3; // x.a == 1, y.a == 2, z.a == 3
// All variables hold a different copy of the struct
Debug.Assert(x.a == 1);
Debug.Assert(y.a == 2);
Debug.Assert(z.a == 3);

Debug.Assert(x.b == 42);
Debug.Assert(y.b == 42);
Debug.Assert(z.b == 42);

(This fact makes it generally a bad idea to have mutable structs like the one above. I used it just for demonstration purposes. Don't do it on real code. Keep your value types immutable.)

If you had a reference type, you would have a different picture:

class Data { public int a; }
var x = new Data { a = 1 }; // x.a == 1
var y = x; // x.a == 1, y.a == 1
y.a = 2; // x.a == 2, y.a == 2
var z = y; // x.a == 2, y.a == 2, z.a == 2
z.a = 3; // x.a == 3, y.a == 3, z.a == 3
// All variables hold a reference to the same object:
Debug.Assert(x.a == 3);
Debug.Assert(y.a == 3);
Debug.Assert(z.a == 3);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.