Добавить один объект в несколько массивов и сохранить различия между каждой копией? - PullRequest
0 голосов
/ 12 июня 2019

По сути, я хочу создать один объект, а затем добавить этот объект в группу различных массивов и быть уверенным, что если один массив изменит значения объекта, другие объекты в других массивах не изменят свои значения.

Например, скажем, я объявляю пистолет с 50 пулями, хранящимися в целом числе:

Gun tommygun = new Gun(50);

У меня есть два солдата, каждый со списком пистолетов, и добавляю к каждому пистолет.

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

Солдат 1 стреляет из своего оружия:

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

Это уменьшает патрон Солдата1 на 1. Теперь это будет 49. Уменьшает ли это также патрон Солдата2 для оружия?Если да, то как мне избежать этого, не создав отдельного томмигана для каждого солдата?

Ответы [ 4 ]

5 голосов
/ 12 июня 2019

Создайте отдельный экземпляр объекта пистолета-пулемета для каждого солдата.

Поскольку объекты передаются по ссылке, в данный момент вы делите одно оружие между двумя солдатами.

1 голос
/ 12 июня 2019

Другой вариант - реализовать метод Clone в классе Gun. Вы можете использовать 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());
1 голос
/ 12 июня 2019

Похоже, вы новичок в ООП

Есть 2 способа подойти к

  1. Создание нового экземпляра пистолета
  2. Создать Клон из пистолета
0 голосов
/ 12 июня 2019

Вам необходимо выполнить глубокое копирование. В противном случае ваши объекты 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;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...