I’ve recently tried to create a property for a Vector2 field, just to realize that it doesn’t work as intended.
public Vector2 Position { get; set; }
this prevents me from changing the values of its members (X & Y)
Looking up information on this, I read that creating a property to a Vector2 struct returns only a copy of the original object and not a reference.
As a Java developer this confuses me.
When are objects in C# passed by value and when are they passed by reference?
Are all struct objects passed by value?
It is important to realise that everything in C# is passed by value, unless you specify
reforoutin the signature.What makes value types (and hence
structs) different from reference types is that a value type is accessed directly, while a reference type is accessed via its reference. If you pass a reference type into a method, its reference, not the value itself, is passed by value.To illustrate, imagine we have a class
PointClassand a structPointStruct, defined analogously (omitting irrelevant details):And we have a method
SomeMethodthat takes these two types by value:If we now create two objects and call the method:
… we can visualise this with the following diagram:
Since
pcis a reference, it doesn’t contain the value in itself; rather, it references an (unnamed) value somewhere else in memory. This is visualised by the dashed border and the arrow.But: for both
pcandps, the actual variable is copied when calling the method.What happens if
ExampleMethodreassigns the argument variables internally? Let’s check:Output of
pcandpsafter calling the method:→
ExampleMethodchanged a copy of the values, and the original values are unaffected.This, fundamentally, is what “pass by value” means.
There’s still a difference between reference and value types, and that comes into play when modifying members of the value, not the variable itself. This is the part that trips people up when they are confronted with the fact that reference types are passed by value. Consider a different
ExampleMethod.Now we observe the following result after calling the method:
→ The reference object was changed, whereas the value object wasn’t. The diagram above shows why that is: for the reference object, even though
pcwas copied, the actual value that bothpcandapcreference remains identical, and we can modify that viaapc. As forps, we copied the actual value itself intoaps; the original value cannot be touched byExampleMethod.