Search Unity

Instance safe variables

Discussion in 'Scripting' started by pato2128, Jul 15, 2022.

  1. pato2128

    pato2128

    Joined:
    Oct 6, 2017
    Posts:
    3
    I recently realized that the private variables are accessible from other instances of the same class. How could I make something be read from other instances but unable to change them?
    I have for example this code:

    Code (CSharp):
    1. public class Tile : MonoBehaviour
    2. {
    3.     private readonly List<Tile> _neighbours = new List<Tile>();
    4.     private bool _walkable;
    5.  
    6.     public void InitTile(bool walkable)
    7.     {
    8.         _walkable = walkable;
    9.     }
    10.  
    11.     public void AddNeighbour(Tile neighbour)
    12.     {
    13.         if (neighbour._walkable)
    14.         {
    15.             _neighbours.Add(neighbour);
    16.         }
    17.     }
    18. }
    if I decided to do:
    neighbour._walkable = true;
    I could do that thus I don't believe that my code is safe. Even properties with private set have the same effect. Ideally the variable would be readonly but then I don't know how to initialize it.

    PS: The Tile component is on a prefab with a 3Dmodel and some other components.

    Thanks in advance!
     
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,930
    You realise those private values only exist in each of those instances, right? One private value in one instance is not the same private value in another instance.
     
  3. pato2128

    pato2128

    Joined:
    Oct 6, 2017
    Posts:
    3
    Yes, but through the AddNeighbour function, I can see the values of another instance. Besides _walkable, I have more private variables (like for example the Tile Coordinates) and I have access to all of them, both to see their values and the ability to change them.
    As you can see I have a List of Tiles so when I iterate it in another function, I can change whichever variable I want. Thus my question, is it possible to not be able to change the values of private variables of another instance, or if I ask it like this, is it possible to make the variables readonly after the initialization?
     
  4. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,930
    Yeah fair point.

    Normally you'd used the readonly keyword, ensuring a value can't be changed once initialised via a constructor. But since this isn't an option with UnityEngine.Object's, you'd probably want to use the in keyword, preventing parameters from being modified.
     
  5. pato2128

    pato2128

    Joined:
    Oct 6, 2017
    Posts:
    3
    Yes, but if I understand it correctly, that would only work for the InitTile method. Other methods such as AddNeighbour can still access the variables and change them.
    I guess one solution would be to split the class into two new classes, one MonoBehaviour with all the functionality and one data holder with all the data passed in through the constructor and all the variables being readonly? So whenever I want to check if another Tile is walkable I can use
    neighbour.GetComponent<TileInfo>().Walkable;
    and that way I know that the data could never be changed.

    EDIT: If Unity implements the init setter then the variables will be immutable thus this problem will be solved. Hopefully, that feature comes soon.
    https://docs.unity3d.com/2021.3/Documentation/Manual/CSharpCompiler.html
     
    Last edited: Jul 15, 2022