InsertWords()函数无意中修改了文本变量。如果变量text.text为“ exampleˣhere”,而变量text.words [0]为“ TEST”,则InsertWords()函数会将text.text更改为“ example TEST here”。我希望text变量保持不变,而只有textCopy变量更改。我该怎么办?为什么即使我从未使用过regex.Replace,text.text仍会更改?
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;
}
}
答案 0 :(得分:3)
要拥有一个类的副本,您需要创建该类的新实例。您可以使用这样的构造函数来实现。我也将您所有的字段都更改为属性。
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 :(得分:1)
另一种更“流畅”的方法是创建返回新实例的方法,这些实例明确说明正在发生的变化。这样一来,您就可以使整个对象变得不可变,并最大程度地重用不变的嵌套对象,其他人也更容易理解。
例如,无需克隆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);
}