There are several ways to concatenate and format strings in C# and below the most common are listed. I do not take performance into this consideration as these methods are very close when looking at benchmarks. Also Performance is often not an issue - I believe readability of code is better than a tiny bit of extra performance in most cases.
The old fashioned way
int one = 1, two = 2, three = 3;
var testString = one + " plus " + two + " is " + three;
I just thought I would have this, as an honourable mention. This method of concatenating a string is good in the sense that all developers will get it. This will be understood by programmers from all modern programming languages. But that is also where my appraisal of this method ends. Concatenating strings this way is great if you only need to concatenate two strings. But as soon as you have several values and substrings things start to get messy. This is where the other ways come in handy.
String.Format
int one = 1, two = 2, three = 3;
var testString2 = string.Format("{0} plus {1} is {2}", one, two, three);
String.Format was my favourite way to format strings until the arrival of string interpolation (up next). It makes it easy to place values in the middle of a string and it is great for readability. Simply replace the values you want within the string with {0}, where 0 is the index of the parameter you want to use for replacement.
String interpolation
int one = 1, two = 2, three = 3;
var testString3 = $"{one} plus {two} is {three}";
String Interpolation came around in c# 6 and comes with Visual Studio 2015. This is one of the caveats about string interpolation (and all other new features) - not everyone has the newest version of Visual Studio and C#. This means that everyone on your team needs to be up to date or they will get build/compile errors.
Other than that, String interpolation brings readability to a whole new level. It is easy to read and it is very compressed. It is also easy to use - it starts with a $ and then you just add the values you want inserted into the string in curly braces. There is no need to play around with indexes like when using string.format. At compile time it is transformed into a string.format, so all in all, it is just sugar syntax for a string.format.
String builder
I thought I should mention the StringBuilder here at the end. I do not see the string builder as a means to get readability, but rather performance. I would go so far as to say that this sacrifices readability for performance:
int one = 1, two = 2, three = 3;
var sb = new StringBuilder(20);
sb.AppendFormat("{0} plus {1} is {2}", one, two, three);
As you can see above, it is not as concise as the previous examples, however if you plan to do several mutations of a string you should consider using StringBuilder. In this post on stackoverflow you can find more information on its performance.
That is it!
If you feel that I missed something on this list, please write it in the comments below! If you enjoyed this post, please share that as well :)