{"id":326408,"date":"2023-02-27T16:33:44","date_gmt":"2023-02-27T15:33:44","guid":{"rendered":"https:\/\/blog.jetbrains.com\/?post_type=dotnet&#038;p=326408"},"modified":"2023-03-14T17:35:09","modified_gmt":"2023-03-14T16:35:09","slug":"raw-strings-utf-8-strings-multiline-interpolations-using-csharp-11-in-rider-and-resharper","status":"publish","type":"dotnet","link":"https:\/\/blog.jetbrains.com\/en\/dotnet\/2023\/02\/27\/raw-strings-utf-8-strings-multiline-interpolations-using-csharp-11-in-rider-and-resharper","title":{"rendered":"Raw Strings, UTF-8 Strings, and Multiline Interpolations \u2013 Using C# 11 in Rider and ReSharper"},"content":{"rendered":"\n<figure class=\"alignright is-resized\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2017\/09\/dotnet-csharp.png\" alt=\"ReSharper and Rider support for C# 11\" class=\"wp-image-16074\" width=\"200\" height=\"200\" style=\"margin: 10px\"><\/figure>\n\n\n\n<p>The .NET 7 SDK arrived a few months ago, with many .NET developers looking forward to this release and the brand-new C# language features that come along with it. If you haven&#8217;t put your fingers on it yet, all you need is:<\/p>\n\n\n\n<ul><li>Download the <a href=\"https:\/\/dotnet.microsoft.com\/en-us\/download\/dotnet\/7.0\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">latest .NET SDK<\/a><\/li><li>Update your <code>global.json<\/code> if you have one<\/li><li>Update the <code>TargetFramework<\/code> in your project to <code>net7.0<\/code> (only for some features)<\/li><li>Update the <code>LangVersion<\/code> property in your project to <code>11.0<\/code> or <code>preview<\/code><\/li><\/ul>\n\n\n\n<p>In this series, we will dive into the most interesting features that are coming with C# 11 and show how we updated ReSharper and Rider to support you in applying them to your codebase with ease:<\/p>\n\n\n\n<ul><li><a href=\"https:\/\/blog.jetbrains.com\/dotnet\/2023\/02\/20\/list-and-span-pattern-matching-using-csharp-11-in-rider-and-resharper\/\">List and Span Pattern Matching<\/a><\/li><li><a href=\"https:\/\/blog.jetbrains.com\/dotnet\/2023\/02\/27\/raw-strings-utf-8-strings-multiline-interpolations-using-csharp-11-in-rider-and-resharper\/\"><strong>Raw Strings, UTF-8 Strings, and Multiline Interpolations<\/strong><\/a><\/li><li><a href=\"https:\/\/blog.jetbrains.com\/dotnet\/2023\/03\/06\/required-keyword-checked-operators-nameof-operator-scope-using-csharp-11-in-rider-and-resharper\/\">Required Keyword, Checked Operators, nameof Operator Scope<\/a><\/li><li><a href=\"https:\/\/blog.jetbrains.com\/dotnet\/2023\/03\/14\/static-interface-members-generic-attributes-auto-default-structs-using-csharp-11-in-rider-and-resharper\/\">Static Interface Members, Generic Attributes, Auto-Default Structs<\/a><\/li><\/ul>\n\n\n\n<p>This second post will walk you through raw strings, multiline string interpolation, and the new UTF-8 string literals.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Raw Strings<\/h2>\n\n\n\n<p>Embedding text and code fragments into string literals becomes difficult once they contain characters that need to be escaped, for example, double-quotes for HTML tag attributes or backslashes in Windows paths. ReSharper and Rider got the <a href=\"https:\/\/www.jetbrains.com\/help\/resharper\/Smart_Paste.html\" target=\"_blank\" rel=\"noreferrer noopener\">Smart Paste<\/a> feature onboard, which helps you to escape a string after it is pasted. Though, there is no particular help when writing strings from scratch.&nbsp;<\/p>\n\n\n\n<p><a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/tokens\/verbatim\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Verbatim strings<\/a> reduce the friction of escaping to some degree, e.g., you don\u2019t need to escape backslashes, and you can define multiline fragments. However, the following JSON example illustrates that there are still tradeoffs to deal with, for example, the <strong>escaping of double-quotes and an inevitable misalignment<\/strong> of the fragment in itself and related to the surrounding code:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class Class\n{\n    public void Method()\n    {\n        \/\/ some code\n        var json = $@\"{{\n    \"\"name\"\": \"\"Lucy\"\",\n    \"\"age\"\": 32\n}}\";\n        \/\/ more code\n    }\n}<\/pre>\n\n\n\n<p><strong>With raw strings from C# 11, these are problems of the past.<\/strong> Raw strings are delimited by 3 double-quotes at the start and end of the literal. Inside these strings, you can <strong>freely use up to 2 consecutive double-quotes<\/strong> without any escaping, as in the following JSON example:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">var json = \"\"\"{\"name\":\"Lucy\",\"age\":32}\"\"\";<\/pre>\n\n\n\n<p>But wait. What should you do if your text fragment contains more than 2 double-quotes in a sequence? Well, the C# language team has a simple solution: just add another double-quote to delimit the raw string! Because \u2013 to be more precise \u2013 a raw string is delimited by <em>at least<\/em> 3 double-quotes. For the sake of the argument, let\u2019s consider for a moment that JSON properties are enclosed with 3 double-quotes:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">var json = \"\"\"\"{\"\"\"name\"\"\":\"\"\"Lucy\"\"\",\"\"\"age\"\"\":32}\"\"\"\";<\/pre>\n\n\n\n<p>Pretty neat, huh? This game can be continued with whatever chain of double-quotes you need. You just need to add more double-quotes to the start and end. To put it with Mads Torgersen\u2019s words, &#8220;you can always win&#8221;.<\/p>\n\n\n\n<p>Raw strings also elegantly <strong>solve the alignment problem of multiline fragments<\/strong>. Both the start and end delimiters can be put onto their own line to not obstruct the readability of the fragment and without introducing line breaks in the resulting string (as opposed to verbatim strings). In addition, the closing delimiter indicates how much indentation is automatically removed from the string. That means that the fragment can be properly aligned according to the surrounding code and doesn\u2019t stick to the very left:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">var json = \"\"\"\n    {\n        \"name\": \"Lucy\",\n        \"age\": 32\n    }\n    \"\"\";<\/pre>\n\n\n\n<p>As expected, raw strings <strong>can also be combined with <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/tokens\/interpolated\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">string interpolation<\/a><\/strong>. And indeed, in order to use braces <code>{}<\/code> unescaped (i.e., without opening an interpolation hole), the same game as for double-quotes applies: increase the amount of leading <code>$<\/code> to the number of <code>{<\/code>\/<code>}<\/code> you want to use without escaping them in the string:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">var json = $$\"\"\"This is pretty {{{1030 + 307}}}!\"\"\";\n\/\/ This is pretty {1337}<\/pre>\n\n\n\n<p><strong>ReSharper and Rider both support raw strings in various forms.<\/strong> We&#8217;ve added a new <em>To Raw String<\/em> context action, which allows you to convert all verbatim strings in your solution <a href=\"https:\/\/www.jetbrains.com\/help\/rider\/Coding_Assistance__Context_Actions.html#scope\" target=\"_blank\" rel=\"noreferrer noopener\">in one go<\/a>:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default\"><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/02\/csharp11-raw-strings-convert.png\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/02\/csharp11-raw-strings-convert.gif\" alt=\"Converting Strings to Raw Strings\" width=\"600\"><\/figure>\n\n\n\n<p>It&#8217;s easy to miss the alignment between the content and the closing delimiter, so ReSharper and Rider will let you know ahead of compilation when there is an issue:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default\"><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/02\/csharp11-raw-strings-error.png\" alt=\"Error on Misalignment in Raw Strings\" width=\"900\"><\/figure>\n\n\n\n<p>Of course, we&#8217;ve also updated our existing features to properly work with raw strings, including <a href=\"https:\/\/blog.jetbrains.com\/en\/dotnet\/2023\/01\/12\/language-injection-improvements-in-rider-2022-3\">language injections<\/a> and context actions to insert interpolations. In this example, note that the correct number of <code>$<\/code> signs is added to the front of the raw string: <\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default\"><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/02\/csharp11-raw-strings-interpolation.png\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/02\/csharp11-raw-strings-interpolation.gif\" alt=\"Converting Strings to Raw Strings\" width=\"600\"><\/figure>\n\n\n\n<p>Speaking of string interpolation&#8230;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Multiline String Interpolation<\/h2>\n\n\n\n<p>Sometimes, our expressions in interpolated string holes get a little more complex. <strong>Up until C# 10, we had two choices.<\/strong> Either we keep them as one-liners and accept the sub-optimal readability &#8230;<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Console.WriteLine($\"We welcome you to our {allEvents.Where(x => x.Date >= DateTime.Today).OrderBy(x => x.Name).Select(x => x.Name).JoinComma()} events.\");<\/pre>\n\n\n\n<p>&#8230; or we introduce another variable, but with the downside that it might bloat our method:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">var events = allEvents.Where(x => x.Date >= DateTime.Today).OrderBy(x => x.Name).Select(x => x.Name);\n\/\/ more variables\nConsole.WriteLine($\"We welcome you to our {events.JoinComma()} events.\");\n\/\/ more console output<\/pre>\n\n\n\n<p><strong>With C# 11, you can freely span your interpolation holes across multiple lines<\/strong> and align\/format them to your preferences for better readability. Maybe you still prefer to extract some code, but it\u2019s really nice to have the choice and be able to write the above like this instead:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Console.WriteLine($\"We welcome you to our {\n        allEvents.Where(x => x.Date => DateTime.Today)\n            .OrderBy(x => x.Name)\n            .Select(x => x.Name)\n            .JoinComma()\n    } events.\");<\/pre>\n\n\n\n<p><strong>ReSharper and Rider are ready to help with multiline interpolations.<\/strong> All the string features that you love should work, including the power-user action for <em>Extend Selection<\/em> and <em>Shrink Selection<\/em>:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default\"><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/02\/csharp11-multiline-interpolation.png\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/02\/csharp11-multiline-interpolation.gif\" alt=\"Extending\/Shrinking Selection in Multiline Interpolations\" width=\"500\"><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">UTF-8 Strings<\/h2>\n\n\n\n<p>May it be for the web or plenty of other stacks, UTF-8 is the predominant encoding that developers use. Previously, implementing network communication in .NET based on UTF-8 has often been a choice between <em>efficient but verbose<\/em> or <em>concise but slow<\/em>:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ Verbose + startup allocation + efficient\nstatic readonly byte[] s_authWithTrailingSpace = Encoding.UTF8.GetBytes(\"AUTH \");\nWriteBytes(s_authWithTrailingSpace);\n\n\/\/ Concise + inefficient\nWriteBytes(Encoding.UTF8.GetBytes(\"AUTH \"));<\/pre>\n\n\n\n<p><strong>With C# 11, you can mark your strings as UTF-8 with the <code>u8<\/code> suffix<\/strong>, which will make the compiler do the heavy lifting of turning it into an efficient <code>ReadOnlySpan&lt;byte&gt;<\/code>:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ C#\nWriteBytes(\"HTTP\/1.1\"u8);\n\n\/\/ Decompiled\nWriteBytes(new ReadOnlySpan&lt;byte>((void*) &amp;&lt;PrivateImplementationDetails>.93BA0E8A9E08C993FC2BAC1F290D3C6CB33E2BB1E6825E8DDF78B62BCA2D917A, 8).Length);<\/pre>\n\n\n\n<p><strong>ReSharper and Rider understand the new <code>u8<\/code> literal suffix<\/strong> and many string-related features will work just as you know them, including <a href=\"https:\/\/www.jetbrains.com\/help\/resharper\/Splitting_Lines_with_String_Literals.html\" target=\"_blank\" rel=\"noreferrer noopener\">splitting strings via <kbd>Enter<\/kbd><\/a> or converting them to verbatim\/raw strings:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default\"><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/02\/csharp11-utf8-string-features.png\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/02\/csharp11-utf8-string-features.gif\" alt=\"String Features in UTF-8 Strings\" width=\"500\"><\/figure>\n\n\n\n<p>As with many new language features, the crucial part to success is how quickly you can migrate your codebase to using them. As you might have guessed, we also ship a quick-fix to convert to the leaner UTF-8 string form:<\/p>\n\n\n\n<img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/02\/csharp11-utf8-convert.png\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/02\/csharp11-utf8-convert.gif\" alt=\"Converting to UTF-8 Strings\" width=\"800\">\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>With raw strings, you rarely have to worry about escaping again, and your code will look pretty even in the multiline form. UTF-8 strings are a nice addition that can make high-performance code more readable.<\/p>\n\n\n\n<p>So how about you? Which of the two will you use more often in your codebase? Let us know in the comments! Especially when you have more ideas for additional features in ReSharper and Rider!<\/p>\n\n\n\n<p>Stay tuned for the next blog post, where we will take a look at everything related to keywords and operators!<\/p>\n","protected":false},"author":553,"featured_media":327297,"comment_status":"closed","ping_status":"closed","template":"","categories":[4992,1401],"tags":[158,7073,1398],"cross-post-tag":[],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/dotnet\/326408"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/dotnet"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/types\/dotnet"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/users\/553"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/comments?post=326408"}],"version-history":[{"count":10,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/dotnet\/326408\/revisions"}],"predecessor-version":[{"id":332715,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/dotnet\/326408\/revisions\/332715"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/media\/327297"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/media?parent=326408"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/categories?post=326408"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/tags?post=326408"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/cross-post-tag?post=326408"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}