将一个对象添加到多个数组并保持每个副本之间的差异?

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

基本上,我想创建一个对象,然后将该对象添加到一堆不同的数组中,并确保如果一个数组更改对象的值,则其他数组中的其他对象不会更改它们的值.

例如,假设我声明一把枪有 50 颗子弹存储在一个整数中:

Gun tommygun = new Gun(50);

我有两个士兵,每个人都有一个枪支清单,并为每个人添加一把冲锋枪。

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

士兵 1 开枪:

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

这会使 Soldier1 的弹药减少 1。现在是 49。这是否也会减少 Soldier2 的枪的弹药?如果是这样,我如何在不为每个士兵创建单独的冲锋枪的情况下避免这种情况?

为每个士兵创建一个单独的冲锋枪对象实例。

由于对象是通过引用传递的,此时您正在两个士兵之间共用一把枪。

看来您是 OOP 新手

您可以通过 2 种方法

  1. 创建新的枪支实例
  2. 创建一把Clone的枪

您需要执行深拷贝。否则,您的 Gun 对象就是别名。

using System;
using System.Collections.Generic;

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            Gun g1 = new Gun(50);
            g1.addModification("Scope");
            Gun g2 = (Gun) g1.Clone();
            if (g1 != g2)
                Console.WriteLine("These objects are not aliases");
            Console.WriteLine(g1);
            Console.WriteLine(g2);
            Console.ReadLine();
        }
    }

    class Gun : ICloneable
    {
        int bullets;
        List<object> modifications;
        public Gun(int bullets)
        {
            this.bullets = bullets;
            modifications = new List<object>();
        }

        public void addModification(object o)
        {
            modifications.Add(o);
        }

        public override string ToString()
        {
            return "Bullets: " + bullets + " Modifications: " + modifications[0];
        }

        public object Clone()
        {
            Gun clone = new Gun(this.bullets);
            foreach (object o in this.modifications)
                clone.modifications.Add(o);
            return clone;
        }
    }
}

另一种选择是在 Gun class 上实施 Clone 方法。您可以使用 MemeberwiseClone 创建浅表副本,如果需要,您可以为 Gun 可能具有的任何引用类型属性创建新项。

例如:

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;
    }
}

然后你可以这样做:

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