28

The complete syntax of StringBuilder's Append(string s) function (and similar functions) is

StringBuilder myStringBuilder.Append(string myString)

since myStringBuilder.Append(string myString) already adds the string to myStringBuilder, I was wondering what the return value is for? I have never seen any example code that makes use of the return value.

According to msdn it does not return a new StringBuilder instance but a reference to the current builder itself (that would be myStringBuilder). I just can't think of a scenario when using the return value makes sense at all, why didn't they make the return type void?

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
sth_Weird
  • 620
  • 8
  • 16

2 Answers2

53

It means you can easily chain calls together:

sb.Append("Foo=").Append(foo).Append("&Bar=").Append(bar);

... instead of using several separate statements:

sb.Append("Foo=");
sb.Append(foo);
sb.Append("&Bar=");
sb.Append(bar);

The fact that it's a single expression means you can also use it in places where you're restricted to a single expression, e.g. field initialization or a return statement. The latter means you can use it for expression-bodied members, too:

public override string ToString() =>
    new StringBuilder("x").Append(...).Append(...).ToString();

(In many cases using string.Format or an interpolated string literal would make more sense, but sometimes StringBuilder is the way forward...)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • How stupid of me...I've used StringBuilder like this hundreds of times myself. Abount string.Format: I read that the performance gain of StringBuilder, string.Format and joining strings using "+" varies depending on the number of strings you want to join... – sth_Weird Feb 17 '16 at 07:44
  • @sth_Weird: Yes, but I'd normally go with readability rather than performance unless I knew it was performance-critical. – Jon Skeet Feb 17 '16 at 08:10
10

Just to add more value to Jon Skeet's answer, it would be worth to mention that this is a fluent API design.

It has its pros and cons, but as Jon Skeet has already pointed out, not only with StringBuilder but in many other classes and frameworks, being able to fluently configure or execute things is very interesting.

Maybe the OP has never seen list.Where(x => ...).OrderBy(x => ...).Select(x => ...).ToList(). Or Castle Windsor's fluent configuration API: Component.For<X>().ImplementedBy<Y>().LifeStyleSingleton().

That's why StringBuilder returns the instance from which Append was called: to being able to call other methods as a chain which, sometimes, seems to be easier to understand than many separate sentences.

About the cons

@Jason asked me for the cons in some comment:

Matias, What are the cons?

Taken from my own experience, I believe that there're few cons, but one of most important ones might be that a fluent chain can be harder to debug since you can't go step by step during an interactive debugging session (actually you can step into and step out... but it's less comfortable than going step by step...).

Excepting that con I find fluent design a good way of implementing auto-documented code since sometimes it's just like reading a natural language sentence and keeps things simple (to those that have already got used with fluent design...)

Matías Fidemraizer
  • 63,804
  • 18
  • 124
  • 206
  • I would not call it a fluent API design, as one method does not make a fluent interface! – Ian Ringrose Feb 15 '16 at 11:22
  • 1
    @IanRingrose Well, once you can call a method from the instance returned by the first method in a chain... it seems to be fluent, isn't it? :\ – Matías Fidemraizer Feb 15 '16 at 11:23
  • Matias, What are the cons? – Jason Feb 15 '16 at 18:33
  • 2
    Another issue with such a design is that it can make it less clear whether a method returns a pointer to the original object after altering it, or whether it returns an altered copy of the original object. – supercat Feb 15 '16 at 21:12
  • @supercat Yeah, you're right. I would add it to the answer but I feel that my answer will end up unrelated to this Q&A... :( – Matías Fidemraizer Feb 15 '16 at 21:54
  • @supercat I don't know if there's an existing Q&A about what are the pros and cons of fluent api design... Maybe we can open one and mark it as community wiki :D – Matías Fidemraizer Feb 15 '16 at 21:55
  • Another minor downside is that if one of the calls raises an exception, the stacktrace will be much less informative about which call was the problem. (Or at least, that's true of the Java analogue. I'm not so familiar with the situation in C#.) – ruakh Feb 16 '16 at 01:08