【问题标题】:Why string.Replace("X","Y") works only when assigned to new string?为什么 string.Replace("X","Y") 仅在分配给新字符串时才有效?
【发布时间】:2010-06-01 13:07:16
【问题描述】:

我想它必须与 string 作为引用类型有关,但我不明白为什么简单地 string.Replace("X","Y") 不起作用?

为什么我需要string A = stringB.Replace("X","Y")?我认为这只是在指定实例上完成的一种方法。

编辑:到目前为止,谢谢。我扩展了我的问题:为什么b+="FFF" 有效但b.Replace 无效?

【问题讨论】:

    标签: c# string


    【解决方案1】:

    因为字符串是不可变的。每当您更改字符串时,.net 都会创建一个新的字符串对象。它是类的属性。

    Immutable objects
    String Object

    【讨论】:

    • +1:这是明确的原因。但是,我想说真正的问题是方法的命名。 Replace 暗示实际对象将被操纵。
    【解决方案2】:

    为什么stringA.Replace("X","Y") 不起作用?
    为什么我需要做 stringB = stringA.Replace("X","Y");

    因为字符串在 .NET 中是不可变的。您不能更改现有字符串对象的值,只能创建新字符串。 string.Replace 创建一个新字符串,如果您希望保留对它的引用,您可以将其分配给某个东西。来自文档:

    返回一个新字符串,其中当前实例中出现的所有指定字符串都替换为另一个指定字符串。

    强调我的。


    如果字符串是不可变的,为什么 b += "FFF";工作吗?

    好问题。

    首先注意b += "FFF"; 等价于b = b + "FFF";(除了 b 只计算一次)。

    表达式b + "FFF" 创建一个具有正确结果的新字符串,而不修改旧字符串。然后将对新字符串的引用分配给b,替换对旧字符串的引用。如果没有其他对旧字符串的引用,那么它将有资格进行垃圾回收。

    【讨论】:

      【解决方案3】:

      字符串是不可变的,这意味着一旦创建,就不能再更改。这有几个原因,据我所知主要是为了性能(字符串在内存中的表示方式)。

      另请参阅(其中很多):

      因此,每个字符串操作都会创建一个新的字符串对象。特别是,如果你做类似的事情

      foreach (string msg in messages)
      {
          totalMessage = totalMessage + message;
          totalMessage = totalMessage + "\n";
      }
      

      您实际上可能创建了数十或数百个字符串对象。因此,如果您想更复杂地操作字符串,请遵循 GvS 的提示并使用 StringBuilder。

      【讨论】:

        【解决方案4】:

        字符串是不可变的。任何更改它们的操作都必须创建一个新字符串。

        【讨论】:

          【解决方案5】:

          StringBuilder 支持内联 Replace 方法。

          如果您需要进行大量字符串操作,请使用 StringBuilder。

          【讨论】:

            【解决方案6】:

            为什么 "b+="FFF" 有效,但 b.replace 无效

            因为 += 运算符当然会将结果分配回左侧的操作数。这只是b = b + "FFF"; 的简写。

            一个简单的事实是您不能在 .Net 中更改任何字符串。 没有字符串的实例方法 - 你必须总是将操作的结果分配回某处的字符串引用。

            【讨论】:

            【解决方案7】:

            是的,它是 System.String 的一种方法。但是你可以试试 a = a.Replace("X","Y");

            【讨论】:

              【解决方案8】:

              String.Replace 是字符串类的一个共享函数,它返回一个新的字符串。它不是当前对象的运算符。 b.Replace("a","b") 类似于只有 c+1 的行。所以就像 c=c+1 实际上将 c+1 的值设置为 c 一样,b=b.Replace("a","b") 将返回的新字符串设置为 b。

              【讨论】:

              • 其根本原因是因为字符串是不可变的,即它们无法更改 - 请参阅@Kevin 答案。对我来说,这是微软的一个错误,因为该方法的命名具有误导性。
              • “String.Replace 是共享函数”和“它不是当前对象上的运算符”是什么意思?
              • @James,字符串是不可变的,但变量不是。 OP 似乎想知道为什么变量的值没有改变,但导致问题的是糟糕的命名约定,而不是字符串的不变性。 @Mark,我的措辞很糟糕。我的意思是说它就像一个共享功能,而不是一个。和引用类型一样,它作用于被引用的字符串,而不是引用。
              • @Nat: “但变量不是” 变量本身不是“类型”,所有变量都属于某种类型!因此,在上面的示例中,变量是字符串类型(它是不可变的)。所以我再次重申,变量没有改变的原因是因为字符串是不可变的
              • @Nat:另外,糟糕的命名约定只会误导开发人员,它与为什么你不能更改字符串无关。
              【解决方案9】:

              正如上面每个人所说,字符串是不可变的。

              这意味着当您进行替换时,您会得到一个新字符串,而不是更改现有字符串。

              如果您不将此新字符串存储在一个变量中(例如在它被声明为的变量中),您的新字符串将不会保存在任何地方。

              【讨论】:

                【解决方案10】:

                要回答您的扩展问题,b+="FFF" 等价于 b = b + "FFF",因此基本上您也在此处创建一个新字符串。

                【讨论】:

                  【解决方案11】:

                  只是为了更明确。 string.Replace("X","Y") 返回一个新字符串...但是由于您没有将新字符串分配给任何内容,因此新字符串将丢失。

                  【讨论】:

                    猜你喜欢
                    • 2022-10-26
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2021-11-25
                    • 1970-01-01
                    • 2011-11-07
                    • 1970-01-01
                    • 2023-03-05
                    相关资源
                    最近更新 更多