Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Declaring long strings that use string interpolation in C# 6

I usually wrap long strings by concatenating them:

Log.Debug("I am a long string. So long that I must " +
    "be on multiple lines to be feasible.");

This is perfectly efficient, since the compiler handles concatenation of string literals. I also consider it the cleanest way to handle this problem (the options are weighed here).

This approach worked well with String.Format:

Log.Debug(String.Format("Must resize {0} x {1} image " +
    "to {2} x {3} for reasons.", image.Width, image.Height,
    resizedImage.Width, resizedImage.Height));

However, I now wish to never use String.Format again in these situations, since C# 6's string interpolation is much more readable. My concern is that I no longer have an efficient, yet clean way to format long strings.

My question is if the compiler can somehow optimize something like

Log.Debug($"Must resize {image.Width} x {image.Height} image " +
    $"to {resizedImage.Width} x {resizedImage.Height} for reasons.");

into the above String.Format equivalent or if there's an alternative approach that I can use that won't be less efficient (due to the unnecessary concatenation) while also keeping my code cleanly structured (as per the points raised in the link above).

like image 606
Kat Avatar asked Aug 31 '15 22:08

Kat


People also ask

What is the syntax for string interpolation?

Syntax of string interpolation starts with a '$' symbol and expressions are defined within a bracket {} using the following syntax. Where: interpolatedExpression - The expression that produces a result to be formatted.

How do you add in string interpolation?

An interpolated verbatim string starts with the $ character followed by the @ character. Starting with C# 8.0, you can use the $ and @ tokens in any order: both $@"..." and @$"..." are valid interpolated verbatim strings. To include a brace, "{" or "}", in a result string, use two braces, "{{" or "}}".

Which character should be used for string interpolation?

To identify a string literal as an interpolated string, prepend it with the $ symbol. You can't have any white space between the $ and the " that starts a string literal.

Can we use expressions Inside string interpolation?

The string interpolation result is 'Hello, World!' . You can put any expression inside the placeholder: either an operator, a function call, or even more complex expressions. ${n1 + n2} is a placeholder consisting of the addition operator and 2 operands.


3 Answers

This program:

var name = "Bobby Tables";
var age = 8;
String msg = $"I'm {name} and" +
    $" I'm {age} years old";

is compiled as if you had written:

var name = "Bobby Tables";
var age = 8;
String msg = String.Concat(String.Format("I'm {0} and", name),
    String.Format(" I'm {0} years old", age));

You see the difficulty in getting rid of the Concat - the compiler has re-written our interpolation literals to use the indexed formatters that String.Format expects, but each string has to number its parameters from 0. Naively concatenating them would cause them both to insert name. To get this to work out correctly, there would have to be state maintained between invocations of the $ parser so that the second string is reformatted as " I'm {1} years old". Alternatively, the compiler could try to apply the same kind of analysis it does for concatenation of string literals. I think this would be a legal optimization even though string interpolation can have side effects, but I wouldn't be surprised if it turned out there was a corner case under which interpolated string concatenation changed program behavior. Neither sounds impossible, especially given the logic is already there to detect a similar condition for string literals, but I can see why this feature didn't make it into the first release.

I would write the code in the way that you feel is cleanest and most readable, and not worry about micro-inefficiencies unless they prove to be a problem. The old saying about code being primarily for humans to understand holds here.

like image 198
bmm6o Avatar answered Oct 01 '22 02:10

bmm6o


Maybe it would be not as readable as with + but by all means, it is possible. You just have to break line between { and }:

Log.Debug($@"Must resize {image.Width} x {image.Height} image to {
    resizedImage.Width} x {resizedImage.Height} for reasons.");

SO's colouring script does not handle this syntax too well but C# compiler does ;-)

like image 32
Piotr Nawrot Avatar answered Oct 01 '22 03:10

Piotr Nawrot


In the specialized case of using this string in HTML (or parsing with whatever parser where multiple whitespaces does not matter), I could recommend you to use @$"" strings (verbatim interpolated string) eg.:

$@"some veeeeeeeeeeery long string {foo} 
whatever {bar}"
like image 27
Balint Morasz Avatar answered Oct 01 '22 03:10

Balint Morasz