I have always used the latter example, but it seems as though a good majority of online tutorials use the string.format example. I don't think that there are any real differences in terms of efficiency, my initial thought is so a coder doesn't have to keep breaking the string to insert variables.

The main reason is that it makes translation much easier, because your program does not need to understand the way different languages build up their sentences. For example, many expressions and phrases in French are back-to-front compared to their English translations.
–
JohnLJan 26 '12 at 18:28

Also, each .NET assembly has an intern pool, containing a collection of unique strings. When your code is compiled, all the string literals you reference in your code are added to this pool. If you have a code that looks like this:

"the int is " + i + " and the double is " + d

That makes it 2 strings in the pool.

If you have:

"the int is {0} and the double is {1}"

You have only one String in the pool.

It is a bit more complicated to know when Strings are interned, and when they are not because the compiler has some intelligence when detecting Strings that may not need to be interned sometimes...Check out for example this article which gives more insight into this matter.

I prefer the first way because it allows me to accurately see what the string is going to look like when output. It's very easy to forget to add a space, or to add extra spacing when just appending strings.

I'm sure that there's also a performance benefit to the first way due to not having to create the extra strings; but that's not my primary concern.

By using the first option you can store a commonly used format string and reduce typing needed and make it easier to update the string everywhere its used. Basically the first option allows for DRY to be implemented easily. It is also a much nicer syntax if multiple variables need to be used in a string, like you mentioned.

I think with string.Format() it's easier to see what exactly is the result going to be (so you don't have problems with forgotten spaces or something like that), and it's also easier to type and modify.

If you want to do very simple formatting, using the + plus operator might be easier, but I tend to use it only when concatenating two strings, not more.

To show how string.Format() is easier to modify, consider that you wanted to add a full stop at the end of the sentence in your example: going from string.Format("The int is {0}", i) to string.Format("The int is {0}.", i) is just one character. But going from "the int is " + i to "the int is " + i + '.' is much more.

Another advantage of string.Format() is that it allows you to easily specify the format to use, like string.Format("The int is 0x{0:X}.", i). This is even more important when formatting date.

As for efficiency, string.Format() is most likely slower that simple string concatenations. But code like this is most likely not on a hot path, so it doesn't matter. And if it does, you are probably better off with using StringBuilder.

Use the one that makes your code most readable. Don't worry about performance.

For your example below I prefer B because it is just more readable. But the language translations above also makes sense. Don't let anyone force you into using string.Format, instead read and point to Jeff Atwoods excellent blog on the The Sad Tragedy of Micro Optimizations Theater