It allows you to perform many string operations on a substring of another string without actually calling Substring() and creating a new string object. This is roughly the same as in C you can have a pointer in the middle of a line:
char * s1 = "foo bar"; char * s2 = p + 4;
s2 "is the" string "bar" in a useful sense.
Take, for example, StringSegment.IndexOf() : you can get the index of a character in a segment of a string without first requiring to call Substring() on a large string and allocate a new buffer:
public int IndexOf(char c, int start) { return IndexOf(c, start, Length - start); }
You can trim the StringSegment and remove the spaces:
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); }
These are very cheap operations, without distribution, etc.
You can do all this by playing with indices yourself, but such code is annoying and error prone. You would rather wrap the abstraction around it.
This is also a “deferred” call to String.Substring() . What (hopefully) got is that if you create some of them, most or all of them will never return the actual substring at all.
Take a look at the constructor:
public StringSegment(string buffer, int offset, int length)
The public properties String Buffer , int Offset and int Length are all read-only.
And the Value property:
public string Value { get { if (!HasValue) { return null; } else { return Buffer.Substring(Offset, Length); } } }
Thus, you can create these things relatively cheaply if you want to expose a collection of potentially large "substrings" in some larger line. If no one calls Value.get , Substring will never be called. If you have a lot of them, and the consumer receives only one or two of them, you avoid many calls to Substring() .
As Servy shows, if you call Value twice on the same object, you call Buffer.Substring(Offset, Length); twice, not at all. If you still avoid the 20 other challenges, this might just be a net win. You may wonder why they do not cache the return value from Buffer.Substring() . I do not know if this was unnecessary due to internment, or if this optimization was found in practice so as not to be worth the effort.