C# 如何在.NET Core 2.1中使用String.Create的示例

C# 如何在.NET Core 2.1中使用String.Create的示例,c#,.net-core,C#,.net Core,有人知道这个方法是如何使用的吗?文档有点“轻松” public static string Create<TState> (int length, TState state, System.Buffers.SpanAction<char,TState> action); 创建公共静态字符串(int-length、TState-state、System.Buffers.SpanAction); 需要三件事: 字符串的最后长度。您必须事先知道这一点,因为该方法需要它为用于

有人知道这个方法是如何使用的吗?文档有点“轻松”

public static string Create<TState> (int length, TState state, System.Buffers.SpanAction<char,TState> action);
创建公共静态字符串(int-length、TState-state、System.Buffers.SpanAction);
需要三件事:

  • 字符串的最后
    长度
    。您必须事先知道这一点,因为该方法需要它为用于构造最终字符串的
    Span
    实例安全地创建一个内部固定长度缓冲区
  • 将成为字符串的数据(
    状态
    )。例如,您可能有一个数组缓冲区(例如,通过网络接收的ascii整数),但它可以是任何东西。这是将转换为最终字符串的原始数据。有一个深埋其中的例子,它甚至使用了一个
    Random
    实例。我还看到了一个不完整的示例,用于创建位图图像(可变大小
    state
    input)的base-64编码哈希值(固定长度),但遗憾的是,我无法再次找到它
  • 操作
    lambda函数,用于将
    状态
    转换为最终字符串的字符。
    Create()
    方法将调用此函数,将它为字符串创建的内部
    Span
    和您的
    状态
    数据作为参数传递
  • 对于一个非常简单的示例,我们可以从如下字符数组中创建一个字符串:

    char[] buffer = {'f', 'o', 'o'};
    string result = string.Create(buffer.Length, buffer, (chars, buf) => {
        for (int i=0;i<chars.Length;i++) chars[i] = buf[i];
    });
    
    int[] buffer = {102, 111, 111};
    string result = string.Create(buffer.Length, buffer, (chars, buf) => {
        for (int i=0;i<chars.Length;i++) chars[i] = (char)buf[i];
    });
    
    该功能的存在是因为与传统方法相比,该技术有一些显著的潜在性能优势。例如,您可以将流对象直接传递给
    String.Create()
    (假设您知道最终长度),而不是将流读入缓冲区。这避免了需要分配单独的缓冲区,并避免了一轮复制值(stream=>buffer=>string变成stream=>string)


    调用
    string.Create()
    时,函数会分配一个新字符串,该字符串的大小已由
    length
    参数确定。这是一个(也是唯一一个)堆分配。因为
    Create()
    是字符串类型的成员,所以它可以访问您和我通常看不到的这个新对象的私有字符串数据。它现在使用此访问创建指向新字符串的内部字符数据的内部
    Span
    实例

    这个
    Span
    存在于堆栈上,但作用于来自新字符串的堆内存。。。没有额外的分配,只要
    Create()
    函数返回,它就完全超出了范围,因此一切都是合法和安全的。而且因为它基本上是一个有好处的指针,所以实际上没有溢出堆栈的风险,除非你做了其他可怕的错误

    现在
    Create()
    调用您的
    action
    函数来完成填充字符串的繁重工作。您的
    操作
    lambda可以写入
    Span
    。。。在lamdba执行的过程中,字符串的不可更改性比您可能听到的要小


    操作
    lamdba被查找时,
    Create()
    可以返回新的、随时可用的字符串引用。一切都很好:我们最小化了堆分配,保留了类型安全和内存安全;
    Span
    不再可在任何地方访问,因为堆栈值已被销毁。我们还减少了缓冲区之间不必要的复制,这取决于您的
    操作
    实现。

    对字符串进行快速搜索。Create find.Ha!我读了那个文件,完全忘了它在里面。。。谢谢