41

I am wondering what is the "best practice" to break long strings in C# source code. Is this string

"string1"+
"string2"+
"string3"

concatenated during compiling or in run time?

Scott Lawrence
  • 6,993
  • 12
  • 46
  • 64
Alexander Prokofyev
  • 33,874
  • 33
  • 95
  • 118

10 Answers10

56

It's done at compile time. That's exactly equivalent to "string1string2string3".

Suppose you have:

string x = "string1string2string3"
string y = "string1" + "string2" + "string3"

The compiler will perform appropriate interning such that x and y refer to the same objects.

EDIT: There's a lot of talk about StringBuilder in the answers and comments. Many developers seem to believe that string concatenation should always be done with StringBuilder. That's an overgeneralisation - it's worth understanding why StringBuilder is good in some situations, and not in others.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
45

If the whitespace isn't important then you can use the @ escape character to write multi-line strings in your code. This is useful if you have a query in your code for example:

string query = @"SELECT whatever
FROM tableName
WHERE column = 1";

This will give you a string with line breaks and tabs, but for a query that doesn't matter.

Rune Grimstad
  • 35,612
  • 10
  • 61
  • 76
8

Your example will be concatenated at compile time. All inline strings and const string variables are concatenated at compile time.

Something to keep in mind is that including any readonly strings will delay concatting to runtime. string.Empty and Environment.NewLine are both readonly string variables.

James Newton-King
  • 48,174
  • 24
  • 109
  • 130
4

The concatenation is done at compile time, so there is no runtime overhead.

Maxam
  • 4,043
  • 2
  • 24
  • 25
4

How about the following extension method (which is inspired by common-tags oneLine method)...

using System;
using System.Text.RegularExpressions;
using static System.Text.RegularExpressions.RegexOptions;

namespace My.Name.Space
{
    public static class StringHelper
    {
        public static string AsOneLine(this string text, string separator = " ")
        {
            return new Regex(@"(?:\n(?:\s*))+").Replace(text, separator).Trim();
        }
    }
}

...in combination with the verbatim string literal used as such:

var mySingleLineText = @"
    If we wish to count lines of code, we should not regard them
    as 'lines produced' but as 'lines spent'.
".AsOneLine();

Note that spaces "inside" the string are kept intact, for example:

// foo      bar hello        world.
var mySingleLineText = @"
    foo      bar
    hello        world.
".AsOneLine();

If you don't want newlines to be substituted with spaces, then pass "" as argument to the extension method:

// foobar
var mySingleLineText = @"
    foo
    bar
".AsOneLine("");

Please note: This form of string concatenation is conducted at run time due to the helper-method involved (in contrast to concatenation via the + operator occurring at compile time, as also stated in the accepted answer). So if performance is an issue, go with the +. If you are dealing with long phrases and readability and "ease of use" is the focus, then the approach suggested above may be worth considering.

Felix K.
  • 14,171
  • 9
  • 58
  • 72
  • This doesn't seem to allow escaped quotes inside the string though, ex. \" – rv.kvetch Mar 10 '21 at 15:36
  • Hi, with the Verbatim String Literal `@` you always need to resort to double quotes instead of slashes ("\") to escape quotes, e.g. `@"hello ""{name}"", how are you";` see also: https://stackoverflow.com/a/556141/2477619 – Felix K. Mar 11 '21 at 09:42
  • 1
    ah, neat trick! I stand corrected, thanks – rv.kvetch Apr 05 '21 at 20:03
1

it really depends on what you need. Generally, if you need to concat strings, the best performance in runtime will be achieved by using StringBuilder. If you're referring in source code something like var str = "String1"+"String2" it will be converter into string str = "String1String2" on compilation. In this case you have no concatenation overhead

Tamir
  • 2,503
  • 16
  • 23
  • Your generalisation is too general - if you can perform the whole concatenation in one go, it's usually faster (and more readable) than using StringBuilder. So prefer "x + y + z" to new StringBuilder(x).Append(y).Append(z).ToString(). StringBuilder is useful when there are *repeated* concatenations. – Jon Skeet Nov 12 '08 at 10:22
  • To second Jon's point... StringBuilder is useful when looping etc. For a single set of operations, string.Concat is simpler and works the same. – Marc Gravell Nov 12 '08 at 10:27
  • Thanks Marc - I'd run out of space :) Edited my answer to point to my StringBuilder article though... – Jon Skeet Nov 12 '08 at 10:27
  • + operator is actually calls concat method. If you'll take a look into StringBuilder implementation, it's bit smarter :) – Tamir Nov 12 '08 at 10:32
1

StringBuilder is a good way to go if you have many (more than about four) strings to concatenate. It's faster.

Using String.Concat in you example above is done at compile time. Since they are literal strings they are optimized by the compiler.

If you however use variables:

string a = "string1";
string b = "string2";
string c = a + b;

This is done at runtime.

Sani Huttunen
  • 23,620
  • 6
  • 72
  • 79
  • The "more than 4" is only relevant when looping over a set of data; otherwise, a single call to string.Concat (passing an array if necessary) is identical. – Marc Gravell Nov 12 '08 at 10:28
  • What you're saying is true. http://dotnetperls.com/Content/StringBuilder-Performance.aspx – Sani Huttunen Nov 12 '08 at 10:29
0

Can't you use a StringBuilder?

Echilon
  • 10,064
  • 33
  • 131
  • 217
Damien
  • 13,927
  • 14
  • 55
  • 88
  • 1
    Doing so would make the code less readable *and* less performant. In other words, it would be a bad thing to do. – Jon Skeet Nov 12 '08 at 10:20
  • Fair enough, I thought that if you were doing a lot of concatenation then stringbuilder was recommended? – Damien Nov 12 '08 at 10:23
  • 1
    If you are doing lots of concatenation during runtime, then yes, StringBuilder is recommended. But the example above has static strings, so the compiler already optimizes it down to a single string. – Maxam Nov 12 '08 at 10:24
  • And even if the concatenation is done at runtime, concatenating two strings with "+" is faster than using StringBuilder. – Jon Skeet Nov 12 '08 at 10:25
  • Well, I did say "lots" =) But you're right, I should have qualified that further. – Maxam Nov 12 '08 at 10:27
  • If we wan to keep a constant string (i.e. binding), StringBuilder is not an option. – Chesare Jun 08 '21 at 15:21
0

There´s any way to do it. My favorete uses a string´s method´s from C#. Sample One:

string s=string.Format("{0} {1} {0}","Hello","By"); result is s="Hello By Hello";

-3

StringBuilder will be your fastest approach if you are using any amount of strings.

http://dotnetperls.com/Content/StringBuilder-1.aspx

If you are just doing a few string (5 or less is a good rule) the speed will not matter of what kind of concatenation you are using.

naspinski
  • 34,020
  • 36
  • 111
  • 167
  • String builder is the faster *runtime* solution, but the expression given would be better evaluated at compile time (which i think shouldn't be a problem for the compiler) – peterchen Nov 12 '08 at 13:06