gpt4 book ai didi

c# - String 对象如何在没有 new 关键字或构造函数的情况下分配内存?

转载 作者:太空狗 更新时间:2023-10-29 20:59:10 47 4
gpt4 key购买 nike

在 C# 中,如果我们想创建一个 string 类型的变量,我们可以使用:

string str="samplestring"; // this will allocate the space to hold the string

在C#中,string是一个类类型,所以如果我们要创建一个对象,通常我们必须使用new关键字。那么在没有 newconstructors 的情况下分配是如何发生的呢?

最佳答案

当你写作时

string str="samplestring";

编译器会生成两条指令:

  1. 首先,ldstr从元数据中获取字符串文字;分配必要的内存量;创建一个新的 String 对象并将对它的引用压入堆栈。
  2. 然后 stloc (或其缩写形式之一,例如 stloc.0 )将该引用存储在局部变量 str 中。

请注意,ldstr 只会为每个字符序列分配一次内存。

因此在下面的示例中,两个变量将指向内存中的同一个对象:

// CLR will allocate memory and create a new String object
// from the string literal stored in the metadata
string a = "abc";

// CLR won't create a new String object. Instead, it will look up for an existing
// reference pointing to the String object created from "abc" literal
string b = "abc";

此过程称为 string interning .

此外,如您所知,在 .NET 中,字符串不可变。因此,String 对象的内容在对象创建后不能更改。也就是说,每次连接字符串时,CLR 都会创建一个新的 String 对象。

例如下面几行代码:

string a = "abc";
string b = a + "xyz";

会被编译成下面的IL(当然不完全是):

  1. ldstr 将分配内存并从 "abc" literal
  2. 创建一个新的 String 对象
  3. STLoc 会将对该对象的引用存储在局部变量 a
  4. ldloc 将该引用压入堆栈
  5. ldstr 将分配内存并从 "xyz" literal
  6. 创建一个新的 String 对象
  7. call 将调用 System.String::Concat在堆栈上的这些 String 对象上
  8. System.String::Concat 的调用将分解为数十条 IL 指令和内部调用。简而言之,它将检查两个字符串的长度并分配必要的内存量来存储连接结果,然后将这些字符串复制到新分配的内存中。
  9. STLoc 会将对新创建的字符串的引用存储在局部变量 b

关于c# - String 对象如何在没有 new 关键字或构造函数的情况下分配内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12976371/

47 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com