String 
      “由于 String 的值一旦创建就不能再修改,所以称它是恒定的。看似能修改 String 的方法实际上只是返回一个包含修改内容的新 String。”——MSDN 
      “由 .NET Framework 提供的 System.String 数据类型表示的是一个不可改变的字符串。这意味着每当字符串数据更改时,内存中字符串的原始表现形式都将被破坏,而且将创建一个包含新字符串数据的新的字符串表现形式,这会导致分配内存和解除分配内存的操作。当然,这一切都是在后台进行的,因此实际的开销不会立即显现出来。但分配内存和解除分配内存的操作将导致公共语言运行库 (CLR) 中与内存管理和垃圾回收相关的活动增加,因此系统开销非常高。当字符串变大并且大块的内存被连续快速地分配和解除分配时,此问题尤为突出,就象在大型字符串连接过程中出现的情况一样。尽管这一问题对单用户环境的影响不大,但在服务器环境(例如,在 Web 服务器上运行的 ASP.NET® 应用程序)中,它却可能会导致严重的性能和可缩放性问题。”——《提高 .NET Framework 应用程序的字符串处理性能》 
      注意: 
 

String 重载了==运算符,所以 == 运算符实际调用 String.Equals:     
         /** <summary> 
         /// Equals 方法。 
          /// </summary> 
         public static bool Equals(String a, String b) { 
             if ((Object)a==(Object)b) { 
                 return true; 
             } 
      
             if ((Object)a==null || (Object)b==null) { 
                 return false; 
             } 
      
             return a.Equals(b); 
         } 
          
         /** <summary> 
         /// == 方法。 
         /// </summary> 
         public static bool operator == (String a, String b) { 
            return String.Equals(a, b); 
         }       摘录:clr\src\bcl\NetSourceCode\string.cs

StringBuilder 
      “大多数修改此类的实例的方法都返回对同一实例的引用。由于返回的是对实例的引用,因此可以调用该引用的方法或属性。如果想要编写将连续操作依次连接起来的单个语句,这将很方便。”——MSDN