using public get; private set; in structs.

Im embarking into bigger projects and im starting to have the need to have well defined public and private structures in this case i have a struct Rect that i need to change the position but not the size so i tried to do the following:

 public Rect position {get; private set;}
    
public void Move(Vector2 translation){
    position.position += translation;
     //I need to do more stuff here related to translation
}

The problem is that I cannot modify position.position only position in its entirety and i would like to know how to solve it.

I know thit in this case i could just do the following:

public void Move(Vector2 translation){
    Rect tempRect = position;
    tempRect.position += translation;
    position = tempRect;
}

I would like to have a solution to be able to do the first thing i tried or an explanation of why it does not work.

Hi, Structs are value types in C#, and according to the documentation


“…By default, on assignment, passing an argument to a method, and returning a method result, variable values are copied. In the case of value-type variables, the corresponding type instances are copied.”


When you use {get; private set;} on the property, the compiler will generate code like this from your’s:

private Rect pos;

public Rect position
{
    get { return this.pos; } // creates a copy of the value
    private set { this.pos = value; } // assigns a copy of the original value
}

public void Move(Vector2 translation)
{
    // error, the getter is called automatically 
    // and a copy of the value (which is not a variable) of the property is accessed, 
    // not the property itself
    position.position += translation;  
}

The code automatically calls the getter of the property and position is just a copy of the value of the property in this case, produced by the return statement of the getter, and not the original property or a variable. Rect tempRect = position; is a definition of a variable, so your second code example, which assigns the new variable back to the property, works.


One solution would be to just remove {get; private set;}:

// optionally add [SerializeField] if you need it in the inspector
private Rect position;

public void Move(Vector2 translation)
{
    position.position += translation;
}
// create getter methods manually if needed 

or use a class instead of a Struct.


See also cs1612.