StringSegment类的目的是什么?

Jul*_*iën 12 c#

Microsoft.Extensions.Primitives包lib中,有一个类StringSegment,注释表明它是:

子串的优化表示.

我没有意识到这个特殊的类,直到我发现了aspnet公告#244,声明:Microsoft.Net.Http.Headers转换为使用StringSegments.

仍然,看看StringSegment类的实现,我没有看到它实际服务的目的.我看到一个缓冲区,我想这可能表示对部分字符有更好的操作(也许是'段'部分?).我还看到几个辅助函数,它们与常规字符串中已有的行为密切相关(如果不相同),例如StartsWith/Endswith,Substring等.aspnet -core文档完整地列出了这些函数,但是这也缺乏上下文关于"为什么"它应该被使用.

那么该StringSegment课程的目的到底是什么以及适用于哪种情景呢?

当我操作字符串时,在我的应用程序代码中调用类是否有用?我们能有一个例子,它会有益吗?

15e*_*153 7

它允许您对另一个字符串的子字符串执行各种字符串操作,而无需实际调用Substring()和创建新的字符串对象.它大致类似于C中的方式,你可以有一个指向字符串中间的指针:

char * s1 = "foo bar";
char * s2 = p + 4;
Run Code Online (Sandbox Code Playgroud)

s2 在有用的意义上,"是"字符串"bar".

例如StringSegment.IndexOf():您可以在字符串段中获取字符的索引,而无需先调用Substring()较大的字符串并分配新的缓冲区:

    public int IndexOf(char c, int start)
    {
        return IndexOf(c, start, Length - start);
    }
Run Code Online (Sandbox Code Playgroud)

你也可以"修剪" StringSegment到"删除"空格:

    public StringSegment TrimStart()
    {
        var trimmedStart = Offset;
        while (trimmedStart < Offset + Length)
        {
            if (!char.IsWhiteSpace(Buffer, trimmedStart))
            {
                break;
            }

            trimmedStart++;
        }

        return new StringSegment(Buffer, trimmedStart, Offset + Length - trimmedStart);
    }
Run Code Online (Sandbox Code Playgroud)

这些是非常便宜的操作,没有分配等等.

您可以通过自己玩索引来完成所有这些工作,但这种代码很烦人且容易出错.你宁愿在它周围包裹一个抽象.

这也是一个"延期"的电话String.Substring().(希望)获得的是,如果你创建了许多这些,它们中的大多数或全部将永远不会返回实际的子串.

看一下构造函数:

    public StringSegment(string buffer, int offset, int length)
Run Code Online (Sandbox Code Playgroud)

公共属性String Buffer,int Offsetint Length都是只读的.

Value财产:

    public string Value
    {
        get
        {
            if (!HasValue)
            {
                return null;
            }
            else
            {
                return Buffer.Substring(Offset, Length);
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

所以你可以相对便宜地创建这些东西,如果你想在一些更大的字符串中暴露一个可能很大的"子串"的集合.如果没有人打电话Value.get,Substring从来没有真正被召唤.如果你有很多它们并且消费者只获得其中一个或两个的价值,你就会避免大量的电话Substring().

正如Servy观察到的那样,如果你Value在同一个对象上打了两次电话,你就会打Buffer.Substring(Offset, Length);两次而不是一次打电话.如果你还在避免其他20个电话,这很容易就是净收益.您可能想知道为什么他们没有缓存返回值Buffer.Substring().我不知道这是不是因为实习而不必要,或者如果在实践中发现这种优化不值得付出努力.