1

For example, if I have enemies, and each of the enemies has a class that keeps the points. Then I when an enemy is spawned in, it connects to PointsKeeper.Instance and adds itself to List<EnemyPoints> points

Is there an easy way of knowing if the EnemyPoints that I add do the list, is a reference to the original or a copy?

Example code:

private List<EnemyPoints> points;

public void AddEnemy(EnemyPoints enemy)
{
    points.Add(enemy);
}

public void AddPoint(int enemy)
{
    points[enemy].points++;
}
Richard Muthwill
  • 320
  • 2
  • 16
  • Its the same in Unity as it is in C# in its entirety. [What is the difference between a reference type and value type in c#?](https://stackoverflow.com/questions/5057267/what-is-the-difference-between-a-reference-type-and-value-type-in-c) – Remy Jul 14 '20 at 12:32
  • The question for me really becomes, are you having an issue where you aren't sure if you are dealing with the original reference or not? – Charleh Jul 14 '20 at 15:40
  • @Charleh so say the enemy has a health script, it dies, and it runs `points--` in it's sibling script. Would that also change it in the `List points` in the `PointsKeeper.Instance`? – Richard Muthwill Jul 14 '20 at 15:49
  • No, int is a value type unless you pass it by reference explicitly you are always referring to a copy of the value. – Charleh Jul 14 '20 at 17:41

1 Answers1

1

C# is a pass-by-value language. As such, when you pass a variable to a method, it always passes the value, not a reference.

So, in your second method:

public void AddPoint(int enemy)
{
points[enemy].points++;
}

Your int enemy will actually contain the int value you want to pass.

What makes things a bit more complicated is that in your first method you pass an object:

public void AddEnemy(EnemyPoints enemy)
{
points.Add(enemy);
}

This time, your EnemyPoints enemy variable does not contain the whole object, but the memory address of the instance. So, you are actually passing a value, but that value is a reference to your instance of the object. So in the end you are effectively passing a reference.

In facts, data types are divided in c# docs in value types and reference types. The former hold the real value of the type, the latter holds a reference.

You can check microsoft docs here

kefren
  • 1,042
  • 7
  • 12
  • As I commented for @Charleh: So say the enemy has a health script, it dies, and it runs `points--` in it's sibling script. Would that also change it in the `List points` in the `PointsKeeper.Instance`? It sounds like from your answer that it would pass the reference and yes, the health script would change the value in both the `EnemyPoints` script and the `PointsKeeper.Instance` – Richard Muthwill Jul 14 '20 at 15:52
  • 1
    Yes, the list contains values that are actually references to the objects. So if you access an object through the list, you access the modified objects. By the way, if the GameObject is destroyed when the enemy dies, its place in the list is not removed, but its value will actually be `null`. It’s up to you to remove it from the list. – kefren Jul 14 '20 at 16:18
  • I'll have a look through the Microsoft link you sent :) You're right about the null reference, I'm aware of that but perhaps it can help others! – Richard Muthwill Jul 14 '20 at 16:25
  • I’m glad I helped. If you find my answer sufficiently comprehensive, feel free to mark it as an accepted answer! :) – kefren Jul 14 '20 at 16:30
  • Well, if you access the list element and then mutate it yes, and if it's the same list instance yes, but if you put any of those values into a variable and increment that, it won't update the values in the list unless you assign the variable back to the list. – Charleh Jul 14 '20 at 17:57