【问题标题】:string is immutable and stringbuilder is mutablestring 是不可变的,而 stringbuilder 是可变的
【发布时间】:2009-03-20 09:42:03
【问题描述】:

谁能举例说明


相关讨论: Most efficient way to concatenate strings?

【问题讨论】:

  • 经典.NET面试题

标签: .net


【解决方案1】:
string s = "a";

s += "b"; // this will create a new string object

StringBuilder sb = new StringBuild();
sb.Append("a");
sb.Append("b"); // appends to existing StringBuilder

【讨论】:

  • 这是一个很好的解释..!!
【解决方案2】:

您不能编辑字符串的值,字符串对象的每个方法都返回一个新字符串,而不是更改原始字符串。另一方面,StringBuilder 可以改变它的内容(例如添加新的字符串)。

string original = "the brown fox jumped over the lazy dog";
string altered = original.Insert(original.IndexOf("fox"), "cat");
// altered = the brown cat jumped over the lazy dog

除非您创建一个新字符串,或者将实例重新引用到另一个字符串对象,否则您无法更改原始字符串的内容。

【讨论】:

    【解决方案3】:

    字符串对象是不可变的,一旦创建就不能更改

    string str;
    //new string object constructed. str= new string("string1");
    str="string1";
    //again new object will be constructed str=new string("string1string2");
    str=str+"string2" 
    since a new object is created for every assignment, there is an overhead.
    

    但是,字符串生成器类提供了一种有效的方法来重复将字符串位附加到已构造的对象。

    StringBuilder str=new StringBuilder();
    str.Append("string1");
    str.Append("string2");
    

    性能差异太小,无法在较少的赋值和连接操作上进行比较,但如果我们有更多这些字符串操作,则通过从字符串切换到字符串生成器可以获得显着的性能提升。

    【讨论】:

      【解决方案4】:

      虽然是个老问题,但我想我还是会回答。

      字符串(引用型存储)

      将字符串的值放在托管堆上,并使用指针指向它。如果更改字符串的值,则新值将存储在托管堆中的另一个位置,并且指针将更改为指向新位置。旧值保留在堆上,没有任何指向其位置的指针。最终可能会耗尽堆内存。

      这是一种安全保护措施。它确保除非程序员在物理上更改字符串(实际上是在堆栈上放置一个新值并更改指针),否则系统不能更改字符串。我认为没有办法将指针从堆上的新值更改为堆上的旧值。


      2010 年 10 月 20 日编辑

      StringBuilder(值类型存储)

      不使用托管堆,并且 因此,不使用指向 价值。它创造了一个价值,在 单一位置。其中的价值 单个位置可以在 许多不同的方式。

      StringBuilder(引用型存储)

      将一个对象放在托管堆上,并使用指针指向它。值通过指针放置在对象中。该值可以通过指针进行操作。我认为这意味着如果值发生变化,堆上的地址空间被分配以适应值的扩展或收缩。


      权衡

      Stringbuilder 使用的处理时间几乎可以忽略不计,[在堆上]用于存储的内存更少,并且可以按字节操作其值。

      String 使用更少的处理时间和更多的内存用于存储,因为它无法更改其旧值,也无法处理它们。为字符串分配新值只是将指针指向堆上的另一个位置,并将新值存储在那里。旧值永远留在堆上,没有指针。

      引用型存储和值型存储的比较。

      经验法则

      • System.ValueType 中的任何内容都是值类型。
      • system.ValueType 之外的任何内容都是引用类型。

      最后,一篇文章显示some code tests to prove these points

      【讨论】:

      【解决方案5】:

      在 C++ 中你可以这样做:

      std::string hello = "Hello, world!\r\n";
      hello[7] = 'W';
      

      在 C# 中,您不能这样做。字符串不能更改。

      【讨论】:

        【解决方案6】:

        它们被设为不可变的一些原因:

        • 不可变类型是线程安全的 意味着你可以传递一个字符串 不用担心它已经被改变了。
        • 如果出现以下情况,则安全性更令人担忧 字符串可以更改。

        【讨论】:

          【解决方案7】:

          字符串是不可变的,,

          这意味着一旦声明我们就不能更改字符串。

          字符串生成器是可变的

          这是可以执行的多种操作。我们可以更改字符串..

          【讨论】:

            【解决方案8】:

            字符串的不变性[实例是只读的]

                string s="hi";
                //now let s be address 1000
                s+=" there"; 
                //above concatination causes creation of new instance in address location other than 1000
                //with modified value "hi there"
            

            stringbuilder的可变性[实例可以修改]

                StringBuilder sbr = new StringBuilder("My Favourite Programming Font is ");
                sbr.Append("Inconsolata")
            //append operation only modifies existing instance of sbr rather than creating new instance
            

            更多有趣的例子和详细的讨论强烈推荐关注this link

            String 与 StringBuilder

            • 字符串
            1. 在系统命名空间下
            2. 不可变(只读)实例
            3. 当值发生连续变化时性能会下降
            4. 线程安全
          • StringBuilder(可变字符串)
            1. 在 System.Text 命名空间下
            2. 可变实例
            3. 显示更好的性能,因为对现有实例进行了新的更改

            有关此主题的描述性文章,其中包含大量使用示例 ObjectIDGenerator,关注this link

            Stackeoverflow 相关问题:Mutability of string when string doesn't change in C#?

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-10-02
              • 2023-03-10
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多