如何获取可变字符串列表?

时间:2011-08-02 14:10:09

标签: c# string reference

我有以下代码

  List<String> l = new List<String>();
  String s = "hello";
  l.Add(s);
  s = "world";

当我设置一些断点并完成程序时,在执行最后一行后,列表中的值仍然是hello而不是world

它不应该等于world吗?字符串不是一个对象,我不只是将一个指针插入列表中吗?稍后如果我将字符串更改为指向不同的值(“world”),为什么我的列表仍然引用旧值?

我怎样才能达到理想的效果? 非常感谢!

6 个答案:

答案 0 :(得分:5)

字符串是不可变的,所以不起作用。当您尝试设置它时,实际上是将指针放到旧字符串上并在引擎盖下创建一个新字符串。

要获得所需效果,请创建一个包装字符串的类:

public class SortOfMutableString
{
    public string Value {get;set;}

    public SortOfMutableString(string s)
    { 
        Value = s;
    }

    public static implicit operator string(SortOfMutableString s)
    {
        return s.Value;
    }

    public static implicit operator SortOfMutableString(string s)
    {
        return new SortOfMutableString(s);
    }
}

并在列表中使用此选项。然后引用将指向类,但您可以在其中包含字符串值。为了做得更好,请覆盖implicit强制转换为字符串,以便您甚至不需要看到正在与SortOfMutableString对话。

请参阅Jon Skeet的回答,毫无疑问是对C#中字符串的非常准确的解释,我甚至都不打扰!

替代课程名称:

  • PseudoMutableString
  • ICantBelieveItsNotMutable
  • HappyAndReferenceableString

答案 1 :(得分:4)

您正在更改s引用以引用其他String实例 字符串是不可改变的;无法更改添加到列表中的现有实例。

相反,您可以创建一个具有可写StringHolder属性的可变String类。

答案 2 :(得分:3)

不,它不应该等于world。变量s的值是引用。当您致电l.Add(s)时,该引用会按值传递给列表。所以列表现在包含对字符串“hello”的引用。

现在,您将s的值更改为对字符串“world”的引用。这根本不会改变列表。

区分三个截然不同的概念非常重要:

  • 变量(具有名称和值)
  • 引用(允许您导航到对象的值,或null
  • 一个对象

所以特别是,列表对变量 s一无所知 - 它知道传递给{{1}的 };那个值发生是调用Adds的值,这就是全部。

您可能会发现这些文章很有用:

答案 3 :(得分:1)

不,涉及两个不同的参考。一个叫s,一个叫List[0]。当您说l.Add(s)时,您将列表引用设置为与s相同的地址,但是当您将s分配给“世界”时,s将指向新字符串,让List[0]指向旧字符串。

如果你真的想要做一些类似于你所要求的事情,你需要将字符串包装在另一个包含字符串的对象中,以便sList[0]都引用该对象,然后该对象对字符串的引用可以改变,两者都会看到它。

 public class StringWrapper
 {
     public string TheString { get; set; }
 }

然后你可以这样做:

 var s = new StringWrapper { TheString = "Hello" };
 var l = new List<StringWrapper>();
 l.Add(s);
 s.TheString = "World";

现在l[0].TheString也将成为世界。这是有效的,因为在这种情况下,我们不会更改List [0]或s中的引用,而是它们由s和List [0]引用的对象的内容。

答案 4 :(得分:0)

变量是对象引用,而不是对象本身。 s = "world"说“make s引用字符串"World"” - 它不会以任何方式影响"hello"之前引用的字符串s。 ,C#中的字符串总是不可变的。但是,您可以使第一个列表元素(当前引用"hello")引用不同的字符串:l[0] = "world"

答案 5 :(得分:0)

这里的另外两个答案很好地说明了你为什么尝试没有“工作,但你正在寻找一个解决方案,以达到你想要的效果。将字符串(属性)包装在对象内部。然后你可以改变那个字符串,它将反映在集合中。