Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is C# string interpolation compiled?

Tags:

I know that interpolation is syntactic sugar for string.Format(), but does it have any special behavior/recognition of when it is being used with a string formatting method?

If I have a method:

void Print(string format, params object[] parameters) 

And the following call to it using interpolation:

Print($"{foo} {bar}"); 

Which of the following calls lines is most equivalent to the compiled result of string interpolation?

Print(string.Format("{0} {1}", new[] { foo, bar })); Print("{0} {1}", new[] { foo, bar }); 

Reasoning behind the question: Logging frameworks such as NLog typically defer string formatting until they have determined that a log message will actually be written. In general I prefer the string interpolation syntax, but I need to know if it may incur an extra performance penalty.

like image 556
Merad Avatar asked May 20 '16 15:05

Merad


People also ask

What does %c mean in C?

%d is used to print decimal(integer) number ,while %c is used to print character . If you try to print a character with %d format the computer will print the ASCII code of the character.

How is C written?

So, C is not written in any language. The C language is a set of rules defined on the language specification. In order for a C program run in your machine it is “translated” into binary.

How is C used?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

What is C in simple words?

C Introduction C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.


1 Answers

It is compiled in one of two ways.

If you use a string interpolation expression where a string is expected, it is compiled into a call to string.Format.

Basically, this:

string s = $"now is {DateTime.Now}"; 

is turned into this:

string s = string.Format("now is {0}", DateTime.Now); 

See it for yourself in Try Roslyn.

Nothing magical here.

Now, on the other hand, if you use it in a place where a FormattableString (a new type in .NET 4.6) is expected, it is compiled into a call to FormattableStringFactory.Create:

public void Test(FormattableString s) { }  Test($"now is {DateTime.Now}"); 

The call there is turned into this:

Test(FormattableStringFactory.Create("now is {0}", DateTime.Now)); 

See it for yourself in Try Roslyn.

So in essence, to answer your final question there:

This call:

Print($"{foo} {bar}"); 

Will be translated to this:

Print(string.Format("{0} {1}", foo, bar)); 

which will incur the cost of the formatting through string.Format before Print is even called.

If you could add, or find, an overload of Print that takes a FormattableString, then you could defer the actual cost of string.Format until after you've figured out if you need to log. Whether this has a measurable different in runtime is hard to say.

See it for yourself in Try Roslyn.


Bonus Round

Not only is the actual formatting deferred, but the ToString method of FormattableString allows you to specify a IFormatProvider.

This means that you can defer localized transformation as well.

public static void Print(FormattableString s) {     Console.WriteLine("norwegian: " + s.ToString(CultureInfo.GetCultureInfo("nb-NO")));     Console.WriteLine("us: " + s.ToString(CultureInfo.GetCultureInfo("en-US")));     Console.WriteLine("swedish: " + s.ToString(CultureInfo.GetCultureInfo("sv-SE"))); } 
like image 171
Lasse V. Karlsen Avatar answered Sep 21 '22 15:09

Lasse V. Karlsen