Link to a list that does not change the value

I am moving from Java to C # and coding some sample programs. Now I came across List of different objects (IUnit), and when I make a call to some value in the list to change its value, it changes all the values. I added a link to the List for other questions.

So, I have the following classes

interface IUnit { int HealthPoints { set; get; } String ArmyType { get; } } 

This is the base class that I am calling to create a list of army types (marines / infantry). The implementation is the same; expect the values ​​to change inside the class.

 public class Infantry : IUnit { private int health = 100; protected String armyType = "Infantry"; public int HealthPoints { get { return health; } set { health = value; } } public String ArmyType { get { return armyType; } } 

Then I initialize the list with the following code

  List<IUnit> army = new List<IUnit>(); Infantry infantry = new Infantry(); Marine marine = new Marine(); army.Add(Marine); 

Then I have a method that simply removes 25 of the health points.

  public void ShotRandomGuy(ref List<IUnit> army) { army[0].HealthPoints = army[0].HealthPoints - 25; } 

Then I call this method as shown below.

  battle.ShotRandomGuy(ref army); 

However, he takes 25 from all the objects on this list. How can i stop this? I added a link to the List, so I would think that would remove it from the original list. Do I need to clone a list? Will this work?

Or is it more of a design problem?

Thanks!

+4
source share
3 answers

It looks like you are adding the same instance of the unit many times to the list. Thus, all elements of the list point to one object in memory. Changing any object modifies this object.

 List<IUnit> army = new List<IUnit>(); Infantry infantry = new Infantry(); for(int i = 0; i < 10; i++) { // adds same instance each time army.Add(infantry); } 

You must create a new instance when adding units to the list. For instance.

 List<IUnit> army = new List<IUnit>(); for(int i = 0; i < 10; i++) { // create new instance each time Infantry infantry = new Infantry(); army.Add(infantry); } 

By the way, you do not need ref here:

 public void ShotRandomGuy(List<IUnit> army) { Random r = new Random(); var unit = army[r.Next(army.Count)]; unit.HealthPoints -= 25; } 
+4
source
  • You do not need to pass the list as ref unless you intend to set the army on another list
  • Did you forget to add infantry to the list? Army list = new list (); Infantry infantry = new infantry (); Marine marine = new Marine (); army.Add (naval);
0
source

You can save infantry and marine in lists and sort them with for .

Something like this will work to instantiate the list.

 breadCollection = new List<InteractiveObject>(); for(int i = 0; i < totaltObjects; i++) breadCollection.ElementAt(i).Add(new InteractiveObject()); 

Whenever you need to access the contents of a list to make changes, do something like this.

 int shotUnit?; shotUnit = unitNumber if(shot != null) { breadCollection.ElementAt(i).Remove(alive) breadCollection.ElementAt(i).Add(dead) shotUnit = null; } 

I believe this will work for your problem. You can also write something to change the numerical values ​​of properties using

0
source

Source: https://habr.com/ru/post/1498568/


All Articles