Экземпляр обращается к значению свойства других экземпляров - PullRequest
2 голосов
/ 03 февраля 2020

Моя цель - получить данные из пользовательского интерфейса и сохранить их в виде конфигурации. Программа позволяет настроить несколько человек, поэтому я пытаюсь сохранить настройки каждого человека. Я понял кое-что. Всякий раз, когда я изменяю данные из одного экземпляра, значения других экземпляров меняются.

public class Person()
{
    private string _name;

    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }

    public void Change()
    {
        Name = "F";
    }
}

Это мой личный класс

Это мой основной

static void Main(string[] args)
{
    Person person = new Person();
    Person person2 = new Person();
    Person current = new Person();

    person.Name = "John";
    person2.Name = "Doe";
    current.Name = "Robert";

    person = current;
    person2 = current;
    current.Change()
}

после текущего .Change () имя человека 1 и имя человека 2 меняется на «F». Это привело меня в замешательство, потому что я ожидал, что этот результат будет

    person = current;
    person2 = current;
    current.Change()
    person = current;
    person2 = current;

. Я хочу использовать текущий интерфейс. Получите данные и сохраните их в личных экземплярах. Проблема в том, что когда я меняю текущий, все остальные свойства экземпляра меняются на те же, и я теряю настройки конфигурации.

Как мне достичь своей цели? Есть идеи?

Спасибо большое! Извините за плохой Энгли sh.

1 Ответ

1 голос
/ 03 февраля 2020

Поскольку Person является ссылочным типом, когда вы делаете person2 = current;, вы на самом деле просто указываете ссылку person2 на объект current в памяти, на который также указывает person.

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

Вам необходимо сделать фактическую копию объекта.

Один из распространенных способов сделать это - написать "Конструктор копирования" для создания копии. Вы также можете написать метод Copy(), который использует конструктор копирования для реализации, но в этом нет необходимости, если у вас нет иерархии наследования.

Вот как ваш класс Person будет выглядеть с конструктором копирования и (для полноты) метод Copy():

public class Person
{
    private string _name;

    public Person() // Default constructor is required if there are any other constructors!
    {
        Name = "";
    }

    public Person(Person other) // Copy constructor.
    {
        this.Name = other.Name;
    }

    public Person Copy()
    {
        return new Person(this); // Use copy constructor to return a copy of this.
    }

    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }

    public void Change()
    {
        Name = "F";
    }
}

Затем вы можете использовать это для примера:

static void Main()
{
    Person person  = new Person();
    Person person2 = new Person();
    Person current = new Person();

    person.Name  = "John";
    person2.Name = "Doe";
    current.Name = "Robert";

    person  = new Person(current); // Using Copy Constructor.
    person2 = current.Copy();      // Using Copy() method.
    current.Change();  // Only changes current, not person or person2.
}

Примечание. реализовать метод Copy() и просто придерживаться конструктора копирования, если (как отмечалось ранее) не существует иерархии наследования для вашего класса. Это было бы расширенное использование вне рамок этого ответа !

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