存储对字符串的引用
我有一个有3个字符串属性的类。 我想将它们存储在一个列表中,这样当我对列表的字符串进行更改时,它们也会在类中更新。
如果我使用类对象,这很容易做,但字符串似乎表现不同。 它似乎为列表创建了一个对象的副本,而不是指向该对象的指针。 我该怎么做才是C#? 如果这不可能有更好的方法吗?
string
s的问题在于它们是不可变的。 换句话说,一旦创建了string
,就永远不能更改它。
因此,如果要“更改” string
,则必须从List
删除原始文件,并将结果存储回列表中。 例:
string a = "abcdefg"; List list = new List (); list.add(a); a = a.Substring(0, 5);
该代码不执行任何操作,因为string
a
指向永远不会更改。 它只是指向一个新的string
。
在.NET中,字符串是不可变的。 如果更改字符串,则实际上是在创建新字符串并修改引用。
我会考虑使用StringBuilder对象来解决您的问题。
字符串是不可变的。 您可以更改引用以指向另一个字符串,但您不能修改字符串,以便其他对它的引用也会更改值(除了不安全,完全危险的reflection代码)
你想要做的是通过使用可变替代(例如StringBuilder)或通过显式间接来处理这个问题。 我会告诉你后者:
public class Props { private readonly string[] data = new string[2]; public string Foo { get { return data[0]; } } public string Bar { get { return data[1]; } } public IList ModifyValueButNoInsertsList { get { return data;} } }
实际上你应该考虑在这种情况下实际使用string []而不是IList,因为它清楚地表明插入是禁止的,只是改变了值。 由于string []实现了IList
因此这不太可能成为问题
由于字符串是不可变的,因此最简单的解决方法是将引用存储为具有一个元素的字符串数组。 任何引用该数组的人都会注意到替换该元素。
C#中的字符串是不可变的,因此您无法在C#中更改字符串 – 您只能创建新字符串。
您可能更愿意存储具有字符串成员的类
class StringHolder { public StringHolder(string s) { str = s;} public string str; } ... List l1 = new List (); List l2 = new List (); List l3 = new List (); StringHolder h = new StringHolder("Test\n"); l1.add(h); l2.add(h); l3.add(h); h.str = h.str.Replace("\n","");
现在所有列表都引用相同的StringHolder,并且自然会看到相同的字符串。
另一种选择是在列表中存储StringBuilder对象而不是String。
class StringHolder { public string Value { get; set; } }
保留这些列表而不仅仅是字符串。 然后,您可以获取/设置Value
属性以更新字符串值。
你正在寻找一种可变的字符串。 有很多方法可以创建一个行为符合您需要的类。
最简单的方法是使用StringBuilder对象而不是字符串。 您只需要小心不要创建新的StringBuilder对象,而是改变现有的对象。 根据您的需要,这可能不是最佳选择。
或者,您可以为String创建自己的包装类,您可以自由地操作它。 缺点是您可能必须编写许多存根方法,这些方法根据您的使用方式调用内部字符串。 公开读/写字符串属性会更容易。 这样做的好处是可以让您准确定义所需的行为,但首先需要更长的时间来编写。 同样,您必须确保不创建包装类的新实例,而只是改变类的内部字符串。
将您的字符串包装到自定义类中,这将允许您在许多不同的位置共享它。 您也可以选择存储Char数组。
作为旁注(如有几个提到的那样),如果您正在使用字符串进行一些繁重的处理,请使用StringBuilder类。 由于字符串的不可变性,在循环中改变/连接它们或者你有什么 – 将导致很多开销。
StringBuilder是你的朋友。