Остановить Regex.Replace от изменения исходной переменной - PullRequest
2 голосов
/ 26 января 2020

Текстовая переменная непреднамеренно модифицируется функцией InsertWords (). Если переменная text.text имеет значение «example ˣ here», а переменная text.words [0] имеет значение «TEST», функция InsertWords () изменит text.text на «example TEST here». Я хочу, чтобы текстовая переменная оставалась неизменной, пока изменяется только переменная textCopy. Как бы я это сделал? И почему text.text изменяется, хотя я никогда не использую regex.Replace для него?

public class TextClass {

    public List<string> words;
    public string text;
    public string name;
    public string date;
    public string id;

}

public TextClass text;

public TextClass InsertWords()
    {
        Regex regex = new Regex(Regex.Escape("ˣ"));

        TextClass textCopy = text;

        foreach (string word in inputWords)
        {
            textCopy.text = regex.Replace(textCopy.text, word, 1);
        }

        return textCopy;
    }

Редактировать: я использую функцию, подобную этой

public Display display;

display.DisplayText(InsertWords());

public class Display {

    public Text text;

    public void DisplayText (TextClass text_)
    {
        text.text = text_.text;
    }

}

Ответы [ 2 ]

3 голосов
/ 26 января 2020

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

public class TextClass
{
    // You don't need to set the list externally, just get it to add/remove/iterate
    public List<string> Words { get; } = new List<string>();
    public string Text { get; set; }
    public string Name { get; set; }
    public string Date { get; set; }
    public string Id { get; set; }

    public TestClass() { } // default constructor

    public TestClass(TestClass from) // copy constructor
    {
        Text = from.Text;
        Name = from.Name;
        Date = from.Date;
        Id = from.Id;
        Words.AddRange(from.Words); // this ensures a deep copy of the list
    }    
}

Тогда вы можете сделать

TextClass textCopy = new TextClass(text);

И textCopy будет истинной глубокой копией text, и когда вы назначите что-то на textCopy.Text, и это не повлияет text.Text.

В качестве альтернативы вы можете создать метод копирования, подобный этому

public class TextClass
{
    // You don't need to set the list externally, just get it to add/remove/iterate
    public List<string> Words { get; } = new List<string>();
    public string Text { get; set; }
    public string Name { get; set; }
    public string Date { get; set; }
    public string Id { get; set; }

    public TestClass Copy()
    {
        var copy = new TestClass()
        {
            Text = this.Text;
            Name = this.Name;
            Date = this.Date;
            Id = this.Id;
        }
        copy.Words.AddRange(this.Words); // this ensures a deep copy of the list
        return copy;
    }    
}

И использовать его вот так

TextClass textCopy = text.Copy();
1 голос
/ 26 января 2020

Альтернативный, более «свободный» способ сделать это - создать методы, возвращающие новые экземпляры, которые явно указывают на то, что меняется. Это позволит вам сделать весь объект неизменным и позволит максимально использовать повторно вложенные объекты, которые не меняются; это также будет проще для понимания кем-либо еще.

Нет необходимости клонировать свойство Words для пример:

public class TextClass
{
    // No mutable properties (ideally replace List with IReadonlyCollection too)
    public List<string> Words { get; }
    public string Text { get; }
    public string Name { get; }
    public string Date { get; }
    public string Id { get; }

    public TestClass (List<string> words, string text, string name, string date, string id)
    {
       this.Words = words ?? throw new ArgumentNullException(nameof(words));
       ...
    }

    public TestClass WithNewText(string text) =>
       new TestClass(this.Words, text, this.Name, this.Date, this.Id);
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...