我可以使字符串表现得像参考类型吗?

时间:2009-12-09 09:42:25

标签: c# string immutability

在C#中,字符串是引用类型,但行为类似于值类型。 e.g。

string str = "I am a string";
str.Replace("am", "was");  //str still contains same value, 
//i want it to make "I was a string"

我知道我可以通过

来做到这一点
str = str.Replace("am", "was");

但我不想重新分配它。 反正有没有让它们表现得像参考类型?

其他:

  

我有一个键值对   集合(不是字典),我想要   将一些文本添加到其中   键(字符串),现在我正在删除   键值对然后创建一个   new使用相同的值并添加   在收藏中。我不想要   这样做似乎没有   正确的方式。我想更新密钥   直接

编辑:

我可能从Model获得两个集合,每个集合中的键具有不同的值。所以在View-Model中我想通过在它们前面加上第一个和第二个集合的值来改变键。并且会使所有键都独一无二。

7 个答案:

答案 0 :(得分:10)

使用System.Text.StringBuilder。

如果您不能使用StringBuilder,请尝试阅读http://www.codeproject.com/KB/dotnet/strings.aspx

请参阅“字符串的直接修改”。

答案 1 :(得分:3)

不,字符串是不可变的(一旦创建,就无法更改它们)。但是,如果你真的(我无法想象这对我来说可以接受的情况)需要这个,你可以创建自己的类(让我们将其命名为MutableString),这会暴露类似的公共API字符串,但将在内部处理这些重新分配,并将隐式地从/转换为字符串。

编辑: 请记住重写GetHashCode()和Equals(),否则您的集合将无效。但是 - 建议哈希码保持不变 - 所以基本上,你可以做的就是为每个MutableString返回0。如果您将此作为依赖于哈希码(如词典)的集合中的键使用,那么这将是一个性能问题 - 请注意这一点。

答案 2 :(得分:3)

您的选择基本上是:

  • 独自离开(强烈推荐)
  • 创建自己的字符串类(为什么?如果下游其他开发人员不知道您的意图,将会发生欢闹)
  • 使用StringBuilder以内存轻的方式将字符串连接在一起(可能解决大多数问题)

答案 3 :(得分:3)

不,strings意味着不可变(不可更改)。如果您需要不断追加字符串,请使用System.Text.StringBuilder (MSDN)并使用附加方法。

var sb = new StringBuilder();
sb.Append("I");
sb.Append(" am");
sb.Append(" still");
sb.Append(" a string");
Console.WriteLine(sb.ToString());

答案 4 :(得分:2)

不直接。你需要创建自己的类,而这个类又包含一个字符串,并且有自己的方法来处理Replace等等。

不可避免的问题是 - 为什么?在什么情况下你担心string表现不像它那样?

答案 5 :(得分:2)

不,你不应该这样做。

最好退一步向我们展示您尝试使用可变字符串解决的问题。

编辑,来自评论:

  

我有一个键值对   集合(不是字典),我想要   将一些文本添加到其中   键(字符串),现在我正在删除   键值对然后创建一个   new使用相同的值并添加   在收藏中。我不想要   这样做似乎没有   正确的方式。我想更新密钥   直接

您遇到的问题是没有问题。只需使用s = s.Replace()模式即可。这是正确的(也是唯一的)方式。

使用StringBuilder是可能的,但没有多大帮助,它只能解决实际替换的性能。

如果您想加快速度,则必须显示集合类的API。可以仅替换键/值对中的键。

答案 6 :(得分:2)

您可以创建一个帮助您更新字符串的帮助方法,例如。

public static class StringHelper
{
    public static void Replace(ref string originalStr, string strToReplace, string replaceStr)
    {
         originalStr = originalStr.Replace(strToReplace, replaceStr);
    }
}

用法

var str = "I am a string";
StringHelper.Replace(ref str, "am", "was");