C # print string concatenations

I was often puzzled whether there should be any preference over any of these two preset styles for printing lines that require a minor concat.

string temp = "test"; Console.WriteLine("this is a " + temp); Console.WriteLine("this is a {0}", temp); 

Is there any benefit / harm using one over the other or is it just up to preference?

Thanks.

+4
source share
6 answers

EDITED: my initial answer simply pointed to IL for two methods; my intention was to suggest that Darren sees them as a starting point. Ani (comments) suggested that this is not enough for a clear answer. I also decided to take a look at this, so I posted here a diagram of the process that I proposed to Darren, which, I hope, shows the process of passing, and shows how others can immediately say "o, x uses the string ::. Format"

So: naively, I expect the first to be more efficient since all CLRs need to combine the two lines, while the second uses a generic method that takes an object and therefore needs to convert this object to a string. Even if this conversion is trivial, you still need to go through some plumbing to get to the call, before finally finding that the string does not need a conversion. I looked at IL using ildasm to see what was happening - equally we could use Reflector , which could potentially be more readable.

For what it's worth - I think I'll use StringBuilder.Append from start, anyway.

In the first instance (+), we have a call to String :: Concat (string, string) (which does pretty much what you would expect if you look at IL), and then a Console.WriteLine (string).

  IL_000d: call string [mscorlib] System.String :: Concat (string,
                                                               string)
   IL_0012: call void [mscorlib] System.Console :: WriteLine (string)

Console.WriteLine (string) effectively just calls TextWriter :: WriteLine (string). So much for the first method.

The second method calls Console.WriteLine (string, object):

  IL_000d: call void [mscorlib] System.Console :: WriteLine (string,
                                                                 object)

If we parse Console :: WriteLine (in mscorlib), we see that it calls TextWriter :: WriteLine (string, object):

  .method public hidebysig static void WriteLine (string format,
                                                 object arg0) cil managed
 ...
   IL_0007: callvirt instance void System.IO.TextWriter :: WriteLine (string,
                                                                      object)

which, parsed, calls String :: Format (...):

  .method public hidebysig newslot virtual 
         instance void WriteLine (string format,
                                  object arg0) cil managed
 ...
   IL_0014: call string System.String :: Format (class System.IFormatProvider,
                                                     string

In this case, String :: Format actually creates a StringBuilder with the starting string:

  .method public hidebysig static string Format (class System.IFormatProvider provider,
                                                string format
 ...
   IL_0027: newobj instance void System.Text.StringBuilder ::. Ctor (int32)

then you need to call StringBuilder :: AppendFormat with the object

  IL_0031: callvirt instance class System.Text.StringBuilder System.Text.StringBuilder :: AppendFormat (class System.IFormatProvider,
                                                                                                         string
                                                                                                         object [])

to fill it out. StringBuilder :: AppendFormat must then convert the object so that it can add it as a string before finally calling TextWriter :: WriteLine (string).

To summarize this batch, both end up calling TextWriter :: WriteLine (string), so they differ in that the first calls

  String :: Concat (string, string) 

and the second challenge

  Console :: WriteLine (string, object), 
 TextWriter :: WriteLine (string, object)
 String :: Format (...).  
 String :: StringBuilder (). Ctor
 String :: StringBuilder (). AppendFormat (...)

(and plumbing) basically do the same job.

There an amazing amount happens under the hood in the second. StringBuilder :: ApendFormat is easily the hardest part of everything, and in fact my IL is not good enough to decide if it has an early exit if, for example, it finds out that the object is passed a string ... but the fact that it owes it to consider, means must do some extra work.

Thus, there are major differences between them. The first looks more if you know that you have two lines to combine, which may be useful. It was interesting to see how the first is compared using StringBuilder from the very beginning.

Comments and corrections are welcome .. and hope this helps clarify my answer.

+4
source

As you said, any performance issues on this scale are minor, so use your preferences.

I will use the first method occasionally in a drop prototype or application to prove the concept, but I will use the second method exclusively in everything that can potentially achieve production.

My logic is that the first format is easier and more natural to write fast, but the second is more suitable for reading and serving, for example. how they will change if you need to add a. until the end of the sentence?

 Console.WriteLine("this is a " + temp + "." ); vs Console.WriteLine("this is a {0}.", temp); 
+4
source

If we ignore console output, it is essentially a choice between concatenation and format strings for a single concatenation.

This is a matter of preference.

Personally, I would go with version + in this case - shorter, but equally readable. String formatting really shines when more complex formatting is required than this trivial concatenation, for example, if you need arbitrary characters in the middle of the desired result. As SWeko points out, the version of the format allows for easier maintainability, but this is not the key for me (it’s not difficult to switch from one version to another, all the better, a tool like Resharper can do this on your behalf).

I would point out one fact (not related to 90% of cases): the + version is likely to be a little higher because there is no format string to be parsed at runtime. (As with any other performance issue, you will need to measure your specific cases to justify choosing one of them.)

+2
source

In this case, first one is more readable. Perfromance-wise is also probably tiny faster since there is only one parameter.

Using + concatenator becomes unreadable with several parameters in the middle of stenting.

The second uses String.Format(...) , which internally uses StringBuilder .

+2
source

There are some differences.

The first line creates a new line and sends it to the WriteLine method.

In the second form, WriteLine calls internally string.Format (), which uses StringBuilder internally to create the final string to be written.

In some cases, it is better to use the second form (especially when there are several arguments).

+2
source

readability

From this point of view, if I have many parameters in interspersing text, I will use the latter approach. In the simple case that you showed, I will choose the first one.

Performance

If you use all the lines, they will be equivalent. If, however, you use a lot of parameters and you are interested in performance, I would suggest using the first style and StringBuilder to create the string.

+1
source

Source: https://habr.com/ru/post/1332485/


All Articles