关于System.String的几个认识

1.String分配了之后就无法更改?

下面的代码会造成编译错误:

 

        string s = "hello";
        s[
0]='a';

 

会造成:

Error 3 Property or indexer 'string.this[int]' cannot be assigned to -- it is read only 

事实上是可以改变的:

 

复制代码
        unsafe
        {
            
string s = "hello";
            
fixed (char* p1 = s)
            {
                
*p1='a';
            }
        }
复制代码

 

 

2.String不能用new来构造?

由于代码

 

string s=new string("hello");

 

会报错,没有此类ctor但是实际上string有8个ctor:

 

复制代码
public String(char* value);
public String(char[] value);
public String(sbyte* value);
public String(char c, int count);
public String(char* value, int startIndex, int length);
public String(char[] value, int startIndex, int length);
public String(sbyte* value, int startIndex, int length);
public String(sbyte* value, int startIndex, int length, Encoding enc);
复制代码

 

 

3.字符串“+”会生成新的字符串?

 

string s="he"+"ll"+"o";

 

看看IL:

 

  IL_0000:  nop
  
IL_0001:  ldstr      "hello"
  
IL_0006:  stloc.0
  
IL_0007:  ret

 

事实上是一个字符串,编译器做了我们不知道的事情。

 

4.StringBuilder为什么会比String性能好?

 

String s = null;
for (int i = 0; i < 100; i++)
    s 
+= i.ToString();

 

+实际调用的是String的静态方法public static string Concat(string str0, string str1)

 

复制代码
public static string Concat(string str0, string str1)
{
    
if (IsNullOrEmpty(str0))
    {
        
if (IsNullOrEmpty(str1))
        {
            
return Empty;
        }
        
return str1;
    }
    
if (IsNullOrEmpty(str1))
    {
        
return str0;
    }
    
int length = str0.Length;
    
string dest = FastAllocateString(length + str1.Length);
    FillStringChecked(dest, 
0, str0);
    FillStringChecked(dest, length, str1);
    
return dest;
}
复制代码

 

下面的代码:

 

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100; i++)
    sb.Append(i.ToString());

Append(String)方法:

复制代码
public StringBuilder Append(string value)
{
    
if (value != null)
    {
        
string stringValue = this.m_StringValue;
        IntPtr currentThread 
= Thread.InternalGetCurrentThread();
        
if (this.m_currentThread != currentThread)
        {
            stringValue 
= string.GetStringForStringBuilder(stringValue, stringValue.Capacity);
        }
        
int length = stringValue.Length;
        
int requiredLength = length + value.Length;
        
if (this.NeedsAllocation(stringValue, requiredLength))
        {
            
string newString = this.GetNewString(stringValue, requiredLength);
            newString.AppendInPlace(value, length);
            
this.ReplaceString(currentThread, newString);
        }
        
else
        {
            stringValue.AppendInPlace(value, length);
            
this.ReplaceString(currentThread, stringValue);
        }
    }
    
return this;
}

复制代码

 

通过比较:

string是每次拼接后都需要分配空间,并返回新string的引用。而StringBulder则是预分配空间,而当字符串拼接时,则先检查字符串的空间,再决定是否需要分配新空间。向堆上申请内存空间是比较耗时的操作。

 

 

posted @   DiggingDeeply  阅读(5181)  评论(21编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
点击右上角即可分享
微信分享提示