StringSegment类的目的是什么?

时间:2017-05-24 15:43:22

标签: c#

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

  

子串的优化表示。

我没有意识到这个特定的类,直到我发现aspnet announcement #244,说明: Microsoft.Net.Http.Headers转换为使用StringSegments

但是,看看implementation of the StringSegment课程,我看不出它实际服务的目的是什么。我看到一个缓冲区,我想这可能表示对部分字符有更好的操作('段'部分可能?)。我还看到几个辅助函数,它们与常规字符串中已有的行为(如果不完全相同)密切相关,例如StartsWith / Endswith,Substring等。aspnet-core docs完全列出这些函数,但这也缺乏背景"为什么"它应该被使用。

那么StringSegment类的目的究竟是什么?在哪种情况下它适用于它?

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

2 个答案:

答案 0 :(得分:7)

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

char * s1 = "foo bar";
char * s2 = p + 4;

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

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

    public int IndexOf(char c, int start)
    {
        return IndexOf(c, start, Length - start);
    }

你可以修剪" 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);
    }

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

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

它也是&#34;延期&#34;致电String.Substring()。什么(希望)获得的是,如果你创建了许多这些,它们中的大多数或全部将永远不会返回实际的子串。

查看构造函数:

    public StringSegment(string buffer, int offset, int length)

公共属性String Bufferint Offsetint Length都是只读的。

Value属性:

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

因此,如果您想要公开一系列可能很大的&#34;子串&#34;那么您可以相对便宜地创建这些东西。在一些更大的字符串。如果没有人调用Value.getSubstring永远不会被调用。如果你有很多并且消费者只获得其中一个或两个的价值,那么你已经避免了对Substring()的大量调用。

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

答案 1 :(得分:0)

解析文本时,可能会创建或复制许多新的字符串对象。理论上这个类有助于减少处理大型子串时使用的内存。其他语言也有类似的概念(参见C ++ 17中的std :: string_view)