Изменение одного элемента в массиве объектов изменяет все элементы, c #, как мне назначить объекты по значению - PullRequest
1 голос
/ 03 мая 2019

Я новичок в c # и думаю, что запутался в том, как назначать объекты по значению, а не по ссылке.В следующем коде у меня есть конструктор, принимающий объект по умолчанию для заполнения posGrid.Я хочу, чтобы все они были просто копиями объекта по умолчанию, но когда я изменяю один, все они меняются.Я предполагаю, что это потому, что я инициализирую массив ссылками на объект, но как мне назначить им только значение?

public Grid (int width, int height, Unit defaultUnit)
{
    Random rand = new Random();
    this.width = width;
    this.height = height;

    posGrid = new Unit [height, width];
    for (int y = 0; y < height; y++)
        for (int u = 0; u < width; u++)
            posGrid[y, u] = defaultUnit;
}

Ответы [ 2 ]

0 голосов
/ 03 мая 2019

Есть много способов решить эту проблему.

Самый простой способ - сделать Unit структурой:

struct Unit { ... }

Поскольку structs являются типами значений, копияUnit автоматически создается при назначении чего-либо, а не копируемой ссылки.Однако могут быть некоторые особенности классов, которые вы хотите иметь Unit (например, наличие базового класса), и в этом случае вам нужен другой метод.


В качестве альтернативы, вы можете добавить CreateCopy method:

public Unit CreateCopy() {
    Unit copy = new Unit();
    copy.Property1 = this.Property1;
    copy.Property2 = this.Property2;
    // etc
    return copy;
}

И вызовите его при создании массива:

posGrid = new Unit [height, width];
for (int y = 0; y < height; y++)
    for (int u = 0; u < width; u++)
        posGrid[y, u] = defaultUnit.CreateCopy(); // <----

Этого также можно добиться, реализовав ICloneable.


Третий метод заключается в том, чтобы конструктор Grid принимал все данные, необходимые для создания модуля в качестве параметров, вместо самого объекта Unit.И тогда конструктор может самостоятельно создавать объекты Unit.

public Grid (int width, int height, SomeType defaultUnitProperty1, SomeType defaultUnitProperty2)
{
    Random rand = new Random();
    this.width = width;
    this.height = height;

    posGrid = new Unit [height, width];
    for (int y = 0; y < height; y++)
        for (int u = 0; u < width; u++)
            posGrid[y, u] = new Unit(defaultUnitProperty1, defaultUnitProperty2);
}
0 голосов
/ 03 мая 2019

Типы переменных

Переменные типа int, long являются типами значений и имеют собственное пространство памяти и содержат значение.

Типы ссылок

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

Решение

Итак, для вашей проблемы создайте новыйЕдиница измерения на основе значений defaultUnit.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...