基本上,我想创建一个对象,然后将该对象添加到一堆不同的数组中,并确保如果一个数组更改了对象的值,则其他数组中的其他对象不会更改其值。
例如,假设我声明一把枪,其中 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的新手
您可以通过两种方式处理
- 创建新的喷枪实例
- 创建枪的克隆
您需要执行深层复制。 否则,您的 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;
}
}
}