C# 字符串生成器

C# 字符串生成器是 Dot Net 框架引入的一个概念,旨在解决字符串数据类型的性能问题。我们已经知道,字符串是一种引用类型数据类型,即其变量的内存分配在堆内存中。并且字符串一旦创建就是不可变的,即不能更改。然而,字符串生成器是可变的。

让我们看一个 C# 字符串生成器的示例,以了解其区别。假设

string str = "Hello";

对于上述变量值,将在堆内存中分配 5 字节。接下来,

str = str + “World”;

由于 C# 字符串生成器是不可变的,“World”不会与原始 str 值连接。

相反,将通过将“World”附加到“Hello”来在内存中创建另一个字符串。

堆内存

Hello
Hello World
Hello World ABC
.
.

这样,如果我们尝试修改 100 次,堆中将保留 100 个副本,以及一个原始字符串的副本。总共将保留 101 个副本。

C# 字符串生成器

字符串生成器是可变的,这意味着可以对字符串进行更改。并且 StringBuilder 可从 System.Text 命名空间中获取。

C# 字符串生成器语法如下所示。

StringBulder sb = new StringBuilder(“string str”); // It creates a stringbuilder with the specified string

例如

StringBulder sb = new StringBuilder(“Hello”);

这里 sb 是一个 StringBuilder 对象,它首先分配 16 字节。在修改文本时,它会根据需要将大小加倍。

如果我们知道修改文本需要多少内存的确切大小,那么我们可以将该大小作为参数传递给 C# StringBuilder。

C# 字符串生成器的语法是

StringBuilder sb = new StringBuilder(int length); // It creates an empty stringbuilder with the specified capacity as length

例如

StringBuilder sb = new StringBuilder(1000);

例如,“Hello”占用 5 字节,StringBuilder 分配 16 字节,其中剩余的 11 字节用于将来修改 C# 字符串。

假设“Hello”与另一个“World”连接,即:

sb.Append("World");

如你所知,“Hello World”总共占用了 11 字节,剩下 5 字节为空。

现在一些 ABCDEF 附加到 str

str+=ABCDEF;

Hello World, ABCDEF 需要 18 字节,但只有 16 字节可用。因此,它将内存大小加倍,即增加到 32 字节。

堆内存

Hello World ABCDEF

无论对该变量值进行了多少次更改,字符串生成器在堆内存中只维护一个副本。

注意:如果需要进行三到四次修改,则选择 String 类。如果需要对字符串进行大量更改,则选择 StringBuilder 类。

以下方法对于修改 C# 字符串生成器很有用

方法名称描述
StringBuilder.Append()在当前 StringBuilder 的末尾添加数据
StringBuilder.Insert()在指定索引处向 StringBuilder 插入字符串。
StringBuilder.Remove()从 StringBuilder 中移除指定数量的字符
StringBuilder.Replace()替换指定索引处的指定字符
StringBuilder.AppendFormat()字符串中传递的格式说明符将替换为格式化文本

C# 字符串生成器示例

让我们看一个关于 StringBuilder 的示例代码演示。

using System.Text;

class program
{
  public static void Main()
  {
    string str = "Tutorial";
    StringBuilder sb = new StringBuilder(str);
    sb.Append(" Gateway");
    Console.WriteLine(sb);
    sb.Insert(0, "Welcome To ");
    Console.WriteLine(sb);
    sb.Replace("Welcome To", "Hello!! from");
    Console.WriteLine(sb);
    Console.ReadLine();
  }
}

输出

C# String Builder 1

分析

在这个 C# 字符串生成器示例中,str 是一个字符串变量,初始化为“Tutorial”。

sb 是 StringBuilder 类型的一个对象,str 将作为参数传递给它。

sb.Append(“Gateway”) 将把“Gateway”附加到“Tutorial”。

sb.Insert(0, “Welcome To”) 将把“Welcome To”插入到“Tutorial Gateway”的第 0 个位置。

sb.Replace(“Welcome To”, “Hello!! From”) 将把“Welcome To Tutorial Gateway”中的“Welcome To”替换为“Hello!! from”,并打印

“Hello !! from Tutorial Gateway”

让我们编写代码来了解 StringBuilder 类相对于 String 类的性能。

C# 字符串生成器查找差异

在这里,我们将找出 String 和 StringBuilder 在执行相同次数的迭代时所花费的时间差异。

using System;
using System.Text;
using System.Diagnostics;

class program
{
  public static void Main(string[] args)
  {
    string s = "";
    Stopwatch st = new Stopwatch();
    st.Start();
    for (int i = 1; i <= 5000; i++)
    {
      s = s + i;
    }
    st.Stop();
    StringBuilder sb = new StringBuilder(5000);
    Stopwatch st1 = new Stopwatch();
    st1.Start();
    for (int i=1;i<=5000;i++)
    {
      sb.Append(i);
    }
    st1.Stop();
    Console.WriteLine("Time taken for string: " + st.ElapsedMilliseconds);
    Console.WriteLine("Time taken for StringBuilder: " + st1.ElapsedMilliseconds);
    Console.ReadLine();
  }
}
C# String Builder 2

分析

在这个 C# 字符串生成器示例中,我们将使用一个空的 s。接下来,我们创建了一个 StopWatch 类并为其创建了一个实例 st。此 StopWatch 类来自 System.Diagnostics 命名空间。

st.Start() 将在循环开始之前启动 StopWatch。

我们编写了 C# for 循环,其中 int i 初始化为 1,i 将迭代 5000 次。每次 i 值都与字符串变量 s 连接。

st.Stop() 将停止 StopWatch()。

同样,它还为字符串生成器创建了一个实例 sb,其中 5000 作为参数传递,这意味着 sb 创建了一个容量为 5000 的空字符串。

在循环开始之前,StopWatch 创建了它的实例,并调用了 start()。

这里循环也迭代 5000 次,每次 i 值都附加到它。迭代完成后,StopWatch 停止。

最后,我们使用 StopWatch 类的 ElapsedMilliseconds 属性分别打印了 String 和 StringBuilder 所花费的时间。

在这里,找到差异!String 进行 5000 次迭代需要 20 毫秒,而 String Builder 进行相同次数的迭代需要 1 毫秒。

分类 C#