字符串创建

本文关键字:创建 字符串 | 更新日期: 2024-07-27 20:44:02

我有一个关于在循环中创建字符串的问题。下面是一个代码示例:

 static void Main(string[] args)
    {
        for (int i = 1; i <= 1000000; i++)
        {
            Add(GetStr());
        }
        Console.WriteLine("hmmmmmmmm");
        Console.ReadLine();
    }
    public static string GetStr()
    {
        return "OK";            
    }
    public static void Add(string str)
    {
        list.Add(str);
    }

在上述代码的情况下,将在内存中创建多少个字符串???

字符串创建

在上述代码的情况下,将在内存中创建多少个字符串

一个。(如果包括"hmmmmmmmm",则实际上是两个)

此方法返回常量字符串文字:

public static string GetStr()
{
    return "OK";            
}

它被编译成如下IL代码:

ldstr "OK"
ret

LDSTR操作码将推送对存储在元数据中的字符串文字的引用,RET操作码将返回该引用。

这意味着"OK"将只在元数据中分配一次。列表中的所有条目都将引用该实例。

请注意,字符串文字在默认情况下是内部的。因此,在被拘留之前不会分配"临时字符串",因此不需要垃圾收集。

我修改了你的代码,这样你就可以看到字符串"OK"的内存地址

using System;
namespace ConsoleApplication4
{
  using System.Collections.ObjectModel;
  public class Program
  {
    static unsafe Collection<string> list = new Collection<string>();
    static unsafe void Main(string[] args)
    {
      for (int i = 1; i <= 10; i++)
      {
        Add(GetStr());
      }
      foreach (var str in list)
      {
        fixed (char* ptr = str)
        {
          var addr = (IntPtr)ptr;
          Console.WriteLine(addr.ToString("x"));
        }
      }
      Console.WriteLine("hmmmmmmmm");
      Console.ReadLine();
    }
    public unsafe static string GetStr()
    {
      return "OK";
    }
    public unsafe static void Add(string str)
    {
      list.Add(str);
    }
  }
}

------------控制台输出------------------

如您所见,列表中的字符串"Ok"使用相同的内存引用。

#225bf54
#225bf54
#225bf54
#225bf54
#225bf54
#225bf54
#225bf54
#225bf54
#225bf54
#225bf54
hmmmmmmmm

在您的情况下,代码将创建两个字符串:"OK"answers"hmmmmmmmm"。因为字符串是一个不可变的类型,所以"OK"只会创建一次,每次需要它时,字符串都会被引用。