DEV Community

Cover image for C# 11 Strings in the Raw
Shawn Wildermuth
Shawn Wildermuth

Posted on • Originally published at wildermuth.com on

C# 11 Strings in the Raw

With the release of C# 11, there is a new string in town. It might be getting crazy, but this new “Raw String Literals” is something interesting. Before we dig in, let’s have a refresher about strings:

Simple Strings

Every language needs a type for storing text, that’s the String class/ string keyword. It’s what is used mainly in C# and has been there since day 1:

var text = "I thought we had literal strings";
WriteLine(text);

Enter fullscreen mode Exit fullscreen mode

We could use embedded quotes, but we needed to escape them (or other things like tabs, line breaks):

text = "John \"Quincy\" Adams";

Enter fullscreen mode Exit fullscreen mode

We didn’t have a good solution for multi-line, so we ended up with monstrosities (or using a StringBuilder ):

text = "First Line\n";
text += "Second Line\n";
text += "Third Line";

Enter fullscreen mode Exit fullscreen mode

String Interpolation

Some time, later C# introduced a way to have strings just use interpolation (instead of the dreaded string.Format(…)):

text = $"This is an interpolated string: {someName} - {someName.Length}"; 

Enter fullscreen mode Exit fullscreen mode

The dollar sign said that it should expect C# code inside brackets.

But this introduced a need to double bracket if you needed a bracket in string:

text = $"This is an interpolated string: {{ {someName} }}"; 

Enter fullscreen mode Exit fullscreen mode

A compromise to support this better way of building strings. Of course, that made JSON in strings pretty ugly:

text = $"{{ \"name\": \"Shawn\" }}";

Enter fullscreen mode Exit fullscreen mode

Verbatim Strings

In came Verbatim strings. This allowed you to have line breaks and look simpler:

text = @"This is a verbatim string.

This means you can have line breaks 
and use double ""'s to output quotes.";

Enter fullscreen mode Exit fullscreen mode

While many things didn’t need to be escaped, you still needed something special for double-quotes. If you needed double-quotes you had to double them to get:

This is a verbatim string.

This means you can have line breaks
and use double "'s to output quotes.

Enter fullscreen mode Exit fullscreen mode

Not perfect, but worked in a lot of situations, but if you wanted to use a format like XML or JSON, it ended up with this ugliness:

text = @
{
  ""name"": ""Shawn"
}
";

Enter fullscreen mode Exit fullscreen mode

Verbatim Strings with Interpolation

But you could mix verbatim and interpolation:

text = $@"This is a verbatim 
interpolated string: {someName}";

Enter fullscreen mode Exit fullscreen mode

This worked, unless you needed brackets as text:

// Doesn't work, as it thinks that the whole thing is interpolated
text = $@"
{ 
  ""name"": ""{someName}"" 
}";

Enter fullscreen mode Exit fullscreen mode

So, now we need to double-quote as well as double curly-brace:

// Works
text = $@"
{{ 
  ""name"": ""{someName}"" 
}}";

Enter fullscreen mode Exit fullscreen mode

Hrmph…

Ok, Raw String Literals?

Here’s where Raw String Literals come in. The idea is to allow anything between a set of delimiters. That delimiter is a triple-quote (yes, seriously, but it does make sense).

When you triple-quote, everything is a literal, No magic here:

text = """This is pure text, which includes " and ' and other literals""";

Enter fullscreen mode Exit fullscreen mode

This works, but the rules are a tad different for multi-line, in that case the triple-quotes must be on their own lines:

text = """
Everything between the quotes is literally interpreted, 
There is no need for escaping of anything.

Really!
  You can use "Whatever you Like"
""";

Enter fullscreen mode Exit fullscreen mode

What’s important here is that the triple-quoted lines are not included in the string. The string starts on the first line after the triple-quote. This solves a lot of the messiness with commonly used things like JSON:

text = """
{
  "name": "Shawn"
}
""";

Enter fullscreen mode Exit fullscreen mode

Whew, that’s easy…almost.

Interpolated Raw String Literals?

If you add interpolation to a raw string, you find an odd situation where the compiler must know what is an interpolated section (Raw String Literals assume everything is just text). Like the other types of strings, you start interpolated strings with a dollar sign:

text = $"""<name>{someName}</name>""";

Enter fullscreen mode Exit fullscreen mode

Simple, sure. But what if you need brackets?

// Doesn't work, as it's expecting the brace
// to be part of the interpolation
text = $""" 
{
  "name": "{someName}"
}
""";

Enter fullscreen mode Exit fullscreen mode

The solution? To do interpolation with brackets, the number of dollar-signs represents the number of brackets to indicate an interpolation:

// Add number of $ for the depth of the braces needed
text = $$"""
{
  "name": "{{someName}}"
}
""";

Enter fullscreen mode Exit fullscreen mode

This isn’t a typo, this is valid C# 11. Solves a ton of situations, but still requires you to remember some stuff (I actually wish that had used the back-tick like JavaScript as it reads easier IMO).

What do you think of new new syntax (and do you think you’ll be using it?) Tell me in the comments!

Creative Commons License

This work by Shawn Wildermuth is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Based on a work at wildermuth.com.


If you liked this article, see Shawn's courses on Pluralsight.

Top comments (0)