Search code examples
c#arraysobjectinstance

Add one object to multiple arrays and keep differences between each copy?


Basically, I want to create one object, and then add that object to a bunch of different arrays, and be sure that if one array changes the object's values, the other objects in other arrays don't change their values.

For example, say I declare a gun with 50 bullets stored in an integer:

Gun tommygun = new Gun(50);

I have two soldiers, each with a list of guns Guns, and add a tommygun to each one.

Soldier1.Guns.Add(tommygun);
Soldier2.Guns.Add(tommygun);

Soldier 1 shoots his gun:

Soldier1.Shoot(Soldier1.Guns[0]);

This decreases Soldier1's ammo by 1. It would now be 49. Does this also decrease Soldier2's gun's ammo? If so, how do I avoid that without creating a separate tommygun for every single soldier?


Solution

  • Another option would be to implement a Clone method on the Gun class. You can use MemeberwiseClone to create a shallow copy, and if needed you can then create new items for any reference type properties that Gun may have.

    For example:

    public class Gun
    {
        public int MaxRounds { get; set; }
        public List<Bullet> Ammunition { get; set; } = new List<Bullet>();
    
        public Gun(int maxRounds)
        {
            MaxRounds = maxRounds;
        }
    
        public Gun Clone()
        {
            // Create a shallow copy of all the properties
            Gun newGun = MemberwiseClone() as Gun;
    
            // Because 'Bullet' is a reference type, we need to make a deep copy of 'Ammunition'
            newGun.Ammunition = Ammunition.Select(bullet => bullet.Clone()).ToList();
    
            return newGun;
        }
    }
    
    public class Bullet
    {
        public int Damage { get; set; }
        public int Range { get; set; }
    
        public Bullet Clone()
        {
            return MemberwiseClone() as Bullet;
        }
    }
    

    Then you can do something like:

    Soldier1.Guns.Add(tommygun.Clone());
    Soldier2.Guns.Add(tommygun.Clone());