简体   繁体   中英

c# passing class type member as parameter works as call by value

as i know class type parameter is always passed as reference. but whenever i pass a class type variable which is class member as parameter. it always works like call by value.

public class MapGenerator : MonoBehaviour
{
   [SerializeField]
    private List<MapEntity> stageTerrains = new List<MapEntity>();
    private MapEntity stageTerrain = new MapEntity();

    private void Start()
    {
        RandomChoice(stageTerrains);
    }


    public void RandomChoice(MapEntity mapEntity)
    { 
        mapEntity = stageTerrains[Random.Range(0,selectedList.Count)];
        Print(mapEntity);  //it always works well 
        Print(stageTerrain);  // always print null
    }
}

so i put an ref keyword to parameter and it works as call by reference

public class MapGenerator : MonoBehaviour
{
   [SerializeField]
    private List<MapEntity> stageTerrains = new List<MapEntity>();
    private MapEntity stageTerrain = new MapEntity();

    private void Start()
    {
        RandomChoice(ref stageTerrains);
    }


    public void RandomChoice(ref MapEntity mapEntity)
    { 
        mapEntity = stageTerrains[Random.Range(0,selectedList.Count)];
        Print(mapEntity);  //it always works well 
        Print(stageTerrain);  // print well too 
    }
}

i wonder why passing class type member as parameter is worked like call by value

From the ref documentation

When used in a method's parameter list, the ref keyword indicates that an argument is passed by reference, not by value. The ref keyword makes the formal parameter an alias for the argument, which must be a variable.

So I'll try to explain the makes the formal parameter an alias as simple as possible.

Without ref

Imagine the stageTerrain from private MapEntity stageTerrain = new MapEntity(); as a box holding an address.

Imagine the mapEntity from public void RandomChoice(MapEntity mapEntity) as another NEW box.

  • If you change a property of the mapEntity before assigning a new object, it will also change the value of the calling variable.

When you call the RandomChoice the mapEntity is a new box holding the same memory address as the stageTerrain box.

Now mapEntity = stageTerrains[Random.Range(0,selectedList.Count)]; will assign the selected value only to the New box.

With ref

Imagine the mapEntity from public void RandomChoice(ref MapEntity mapEntity) as an alias for an already existing box that will hold the memory reference just with a different name. (thus the alias statement)

When you call the RandomChoice the mapEntity is the stageTerrain box.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM