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



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

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

Gun tommygun = new Gun(50);

我有两个士兵,每个士兵都有一个枪的清单,并为每个士兵添加一个汤米枪。

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

士兵 1 开枪:

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

这会减少士兵 1 的弹药 1。现在是49岁。这也会降低士兵2的枪的弹药吗?如果是这样,如何在不为每个士兵创建单独的汤米枪的情况下避免这种情况?

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

当对象通过引用传递时,目前您在两个士兵之间共享一把枪。

另一种选择是在Gun类上实现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());

看起来像是OOP的新手

您可以通过两种方式处理

  1. 创建新的喷枪实例
  2. 创建枪的克隆

您需要执行深层复制。 否则,您的 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;
        }
    }
}

最新更新