{"id":499891,"date":"2024-08-07T15:36:30","date_gmt":"2024-08-07T14:36:30","guid":{"rendered":"https:\/\/blog.jetbrains.com\/?post_type=dotnet&#038;p=499891"},"modified":"2024-09-08T19:13:19","modified_gmt":"2024-09-08T18:13:19","slug":"escape-character-extract-common-code-params-modifier-out-vars-csharp-language-support-in-2024-2","status":"publish","type":"dotnet","link":"https:\/\/blog.jetbrains.com\/zh-hans\/dotnet\/2024\/08\/07\/escape-character-extract-common-code-params-modifier-out-vars-csharp-language-support-in-2024-2","title":{"rendered":"Escape Character, Extract Common Code, Params Modifier, Out Vars \u2013 C# Language Support in 2024.2"},"content":{"rendered":"\n<p>Our release for ReSharper and Rider 2024.2 is just around the corner, and we have lots of exciting features shipping for the new C# 13 and current C# and VB.NET! Since there are so many, we will split them into multiple blog posts. So make sure to check those posts out as well!<\/p>\n\n\n\n<p>In this series, we will cover features around:<\/p>\n\n\n\n<ul>\n<li><strong>Escape Character, Extract Common Code, Params Modifier, Out Vars<\/strong><\/li>\n\n\n\n<li><a href=\"https:\/\/blog.jetbrains.com\/dotnet\/2024\/08\/08\/equality-analysis-ref-structs-culture-previews-using-directives-csharp-language-support-in-2024-2\/\" data-type=\"link\" data-id=\"https:\/\/blog.jetbrains.com\/dotnet\/2024\/08\/08\/equality-analysis-ref-structs-culture-previews-using-directives-csharp-language-support-in-2024-2\/\">Equality Analysis, Ref Structs, Culture Previews, Using Directives<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/blog.jetbrains.com\/dotnet\/2024\/08\/09\/cast-expressions-primary-constructors-collection-expressions-list-patterns-csharp-language-support-in-2024-2\/\" data-type=\"link\" data-id=\"https:\/\/blog.jetbrains.com\/dotnet\/2024\/08\/09\/cast-expressions-primary-constructors-collection-expressions-list-patterns-csharp-language-support-in-2024-2\/\">Cast Expressions, Primary Constructors, Collection Expressions, List Patterns<\/a><\/li>\n<\/ul>\n\n\n\n<p>Make sure to download the latest version of ReSharper or Rider to follow along:<\/p>\n\n\n<div class=\"buttons\">\n<div class=\"buttons__row\"><a href=\"https:\/\/www.jetbrains.com\/rider\/download\/\" class=\"btn\" target=\"\" rel=\"noopener\">Download Rider 2024.2<\/a> <a href=\"https:\/\/www.jetbrains.com\/resharper\/download\/\" class=\"btn\" target=\"\" rel=\"noopener\">Download ReSharper 2024.2<\/a><\/div>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\">Escape Character Support<\/h2>\n\n\n\n<p>With C# 13, we are getting a new control sequence for the <a href=\"https:\/\/www.compart.com\/en\/unicode\/U+001B\" target=\"_blank\" rel=\"noopener\">ESC character<\/a>. Previously, you had to use the hexadecimal escape sequence <code>\\0x1B<\/code> to express this character, while now, you can simply use <code>\\e<\/code>. This is especially attractive for <a href=\"https:\/\/learn.microsoft.com\/en-us\/windows\/console\/console-virtual-terminal-sequences\" target=\"_blank\" rel=\"noopener\">virtual terminal sequences<\/a>, which you can use to apply <a href=\"https:\/\/learn.microsoft.com\/en-us\/windows\/console\/console-virtual-terminal-sequences#text-formatting\" target=\"_blank\" rel=\"noopener\">text formatting<\/a> to console applications (including colored, bold, and blinking text).<\/p>\n\n\n\n<p>In 2024.2, we are adding support for the new escape character and allowing you to easily migrate your codebase. As with some other features in this blog post, we&#8217;ve been looking more closely at what other areas in our language support could be improved along the way. So with the <code>\\e<\/code> support, we generalized the simplification inspection to identify other escaping shortcuts, such as <code>\\t<\/code> or <code>\\n<\/code>, to keep your string literals in the most \u201ccanonical\u201d form:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default aligncenter\">\n    <img\n        src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/08\/converting-escape-sequences.jpg\"\n        data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/08\/converting-escape-sequences.gif\"\n        alt=\"Converting escape sequences\"\n        width=\"660\"\/>\n    <figcaption class=\"wp-element-caption\">Converting escape sequences<\/figcaption>\n<\/figure>\n\n\n\n<p>To enhance the handling of escape sequences in C#, we&#8217;ve added a whole set of context actions that allow you to switch between different representations, such as plain text, ASCII text (where non-ASCII characters are replaced with escape sequences), or a sequence of <code>\\u<\/code> and <code>\\x<\/code> Unicode codes. These actions can be applied to escape sequences, entire string literals, or selected character sequences. For instance, if you want to include a non-ASCII symbol in a string literal while maintaining ASCII encoding in the source code, you can use the new <em>Convert to ASCII text<\/em> action:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default aligncenter\">\n    <img\n        src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/08\/converting-to-plain-ascii-and-unicode-text.jpg\"\n        data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/08\/converting-to-plain-ascii-and-unicode-text.gif\"\n        alt=\"Converting to plain, ASCII, and Unicode text\"\n        width=\"660\"\/>\n    <figcaption class=\"wp-element-caption\">Converting to plain, ASCII, and Unicode text<\/figcaption>\n<\/figure>\n\n\n\n<p>Those actions are also useful for uncovering the code points of individual characters. For example, the following two string literals are rendered equally in the editor, but are actually represented by different code sequences:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default aligncenter\">\n    <img\n        src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/08\/inspecting-similar-characters.jpg\"\n        data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/08\/inspecting-similar-characters.gif\"\n        alt=\"Inspecting similar characters\"\n        width=\"660\"\/>\n    <figcaption class=\"wp-element-caption\">Inspecting similar characters<\/figcaption>\n<\/figure>\n\n\n\n<p>Furthermore, we are now warning about ordinary <code>\\x<\/code> escape sequences followed by ASCII letters. Unlike in other programming languages, the <code>\\x<\/code> escaping sequence in C# allows a variable number of hexadecimal characters to follow the prefix (only <code>\\u<\/code> requires exactly 4 hex numbers). That means you could accidentally attach characters to the sequence. The new <em>Avoid mixing variable-length escape sequences and text<\/em> inspection helps you spot such cases:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default aligncenter\">\n    <img\n        src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/08\/mixing-of-escape-sequence-and-text.jpg\"\n        data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/08\/mixing-of-escape-sequence-and-text.gif\"\n        alt=\"Mixing of escape sequence and text\"\n        width=\"660\"\/>\n    <figcaption class=\"wp-element-caption\">Mixing of escape sequence and text<\/figcaption>\n<\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Extract Common Code<\/h2>\n\n\n\n<p>As you hack your way through codebases, it&#8217;s possible that you end up with small to large code duplications. Wouldn&#8217;t it be nice if your IDE told you about them?<\/p>\n\n\n                        <div class=\"rider-code-highlight rider-code-highlight__dark\">\n                <pre><code><span class=\"keyword\">var<\/span> <span class=\"local-name\">sb<\/span> <span class=\"operator\">=<\/span> <span class=\"keyword\">new<\/span> <span class=\"class-name\">StringBuilder<\/span>();\r\n<span class=\"keyword\">var<\/span> <span class=\"local-name\">version<\/span> <span class=\"operator\">=<\/span> <span class=\"class-name\">NuGetVersion<\/span><span class=\"operator\">.<\/span><span class=\"static-symbol method-name\">Parse<\/span>(<span class=\"string\">\"1.3.3.7\"<\/span>)<span class=\"operator\">.<\/span><span class=\"property-name\">Version<\/span>;\r\n\r\n<span class=\"keyword-control\">if<\/span> (<span class=\"local-name\">version<\/span><span class=\"operator\">.<\/span><span class=\"property-name\">Major<\/span> <span class=\"operator\">&gt;=<\/span> <span class=\"number\">5<\/span>)\r\n{\r\n    <span class=\"local-name\">sb<\/span><span class=\"operator\">.<\/span><span class=\"method-name\">Append<\/span>(<span class=\"string\">\"?view=net-\"<\/span>);\r\n    <span class=\"comment\">\/\/ duplicated from here<\/span>\r\n    <span class=\"local-name\">sb<\/span><span class=\"operator\">.<\/span><span class=\"method-name\">Append<\/span>(<span class=\"local-name\">version<\/span><span class=\"operator\">.<\/span><span class=\"property-name\">Major<\/span>)<span class=\"operator\">.<\/span><span class=\"method-name\">Append<\/span>(<span class=\"string\">\".\"<\/span>)<span class=\"operator\">.<\/span><span class=\"method-name\">Append<\/span>(<span class=\"local-name\">version<\/span><span class=\"operator\">.<\/span><span class=\"property-name\">Minor<\/span>);\r\n}\r\n<span class=\"keyword-control\">else<\/span>\r\n{\r\n    <span class=\"local-name\">sb<\/span><span class=\"operator\">.<\/span><span class=\"method-name\">Append<\/span>(<span class=\"string\">\"?view=netcore-\"<\/span>);\r\n    <span class=\"comment\">\/\/ duplicated from here<\/span>\r\n    <span class=\"local-name\">sb<\/span><span class=\"operator\">.<\/span><span class=\"method-name\">Append<\/span>(<span class=\"local-name\">version<\/span><span class=\"operator\">.<\/span><span class=\"property-name\">Major<\/span>)<span class=\"operator\">.<\/span><span class=\"method-name\">Append<\/span>(<span class=\"string\">\".\"<\/span>)<span class=\"operator\">.<\/span><span class=\"method-name\">Append<\/span>(<span class=\"local-name\">version<\/span><span class=\"operator\">.<\/span><span class=\"property-name\">Minor<\/span>);\r\n}<\/code><\/pre>\n                <div class=\"rider-code-highlight-btn-copy\"><div class=\"rider-code-highlight-tooltip\">Copy to clipboard<\/div><\/div>\n            <\/div>\n            \n\n\n\n\n\n\n<p>In 2024.2, we are introducing a new code inspection <em>Extract Common Code<\/em> to analyze code inside branching constructs, more specifically <code>if<\/code> and <code>switch<\/code> statements. This new inspection can detect same code in the beginning and ending of all branching execution paths:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default aligncenter\">\n    <img\n        src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/08\/extracting-common-code.jpg\"\n        data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/08\/extracting-common-code.gif\"\n        alt=\"Extracting common code\"\n        width=\"660\"\/>\n    <figcaption class=\"wp-element-caption\">Extracting common code<\/figcaption>\n<\/figure>\n\n\n\n<p>More importantly, the inspection can also help you catch bugs! Often the equivalent code in branching constructs is the result of copy &amp; pasting code around. The inspection will bring that up to your attention, hinting that the code was supposed to be different. For an easy win, you can hit <code>Alt-Enter<\/code> and look for the <a href=\"https:\/\/www.jetbrains.com\/help\/idea\/running-inspections.html#Specify-inspection-scope\" target=\"_blank\" rel=\"noopener\"><em>Run Inspection By Name<\/em> action<\/a> and find all occurrences in your codebase.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Params Modifier Refactoring<\/h2>\n\n\n\n<p>While we recently investigated <a href=\"https:\/\/blog.jetbrains.com\/zh-hans\/dotnet\/2024\/03\/26\/collection-expressions-using-csharp-12-in-rider-and-resharper\">support for collection expressions<\/a>, we&#8217;ve also revisited related language features such as the <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/keywords\/method-parameters#params-modifier\" target=\"_blank\" rel=\"noopener\"><code>params<\/code> modifier<\/a>, which has been available in C# from day 1. When writing an API, you may not immediately know that you can take advantage of the <code>params<\/code> modifier. On the other hand, once you know it, plenty of code may already have been written. A short example:<\/p>\n\n\n                        <div class=\"rider-code-highlight rider-code-highlight__dark\">\n                <pre><code><span class=\"keyword\">void<\/span> <span class=\"method-name\">M<\/span>(<span class=\"keyword\">string<\/span> <span class=\"parameter-name\">text<\/span>, <span class=\"class-name\">Type<\/span>[] <span class=\"parameter-name\">types<\/span>)\r\n{\r\n    <span class=\"method-name\">M<\/span>(<span class=\"string\">\"plain array\"<\/span>, <span class=\"keyword\">new<\/span>[] { <span class=\"keyword\">typeof<\/span>(<span class=\"keyword\">int<\/span>) });\r\n    <span class=\"method-name\">M<\/span>(<span class=\"string\">\"collection expression\"<\/span>, [ <span class=\"keyword\">typeof<\/span>(<span class=\"keyword\">int<\/span>) ]);\r\n}<\/code><\/pre>\n                <div class=\"rider-code-highlight-btn-copy\"><div class=\"rider-code-highlight-tooltip\">Copy to clipboard<\/div><\/div>\n            <\/div>\n            \n\n\n\n\n\n\n<p>With 2024.2, we are introducing the <em>Add\/Remove &#8216;params&#8217; modifier and update usages<\/em> context actions for C# and VB.NET to improve your API ergonomics and update all usages in one go:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default aligncenter\">\n    <img\n        src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/08\/converting-to-and-from-params-modifier.jpg\"\n        data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/08\/converting-to-and-from-params-modifier.gif\"\n        alt=\"Converting to and from params modifier\"\n        width=\"559\"\/>\n    <figcaption class=\"wp-element-caption\">Converting to and from params modifier<\/figcaption>\n<\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Out Variable Code Completion<\/h2>\n\n\n\n<p>Since C# 7, you can use <a href=\"https:\/\/blog.jetbrains.com\/zh-hans\/dotnet\/2017\/10\/17\/c-7-0-7-1-support-resharper-outvariables\"><code>out<\/code> variable declarations<\/a>, which significantly reduce ceremony when calling methods with <code>out<\/code> parameters. Not only can you capture values right from the argument, but you can also discard them if only the method return value is of importance.<\/p>\n\n\n\n<p>In 2024.2, we decided to finally address this new syntax in our code completion \u2013 including smart naming suggestions! The quickest way for you is to use the <code>ovv<\/code> shorthand:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default aligncenter\">\n    <img\n        src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/08\/code-completion-for-out-var-value.png\"\n        alt=\"Code completion for out var value\"\n        width=\"660\"\/>\n   <figcaption class=\"wp-element-caption\">Code completion for out var value<\/figcaption>\n<\/figure>\n\n\n\n<p>In some cases, the <code>out var<\/code> argument must have an explicit type annotation to help with overload resolution. In this case, our code completion will provide you with all the possible types:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default aligncenter\">\n    <img\n        src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/08\/code-completion-for-out-variable-with-possible-types.png\"\n        alt=\"Code completion for out variable with possible types\"\n        width=\"660\"\/>\n   <figcaption class=\"wp-element-caption\">Code completion for out variable with possible types<\/figcaption>\n<\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>Give it a go with the latest&nbsp;<a href=\"https:\/\/www.jetbrains.com\/resharper\/nextversion\/\" target=\"_blank\" rel=\"noopener\">ReSharper 2024.2 <\/a>and <a href=\"https:\/\/www.jetbrains.com\/rider\/nextversion\/\" target=\"_blank\" rel=\"noopener\">Rider 2024.2<\/a>, and let us know if you have any questions or suggestions in the comments section below.<\/p>\n","protected":false},"author":553,"featured_media":500154,"comment_status":"closed","ping_status":"closed","template":"","categories":[4992,1401,3990,4140],"tags":[158,211,2015,603,756,46,1978,1989],"cross-post-tag":[],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/dotnet\/499891"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/dotnet"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/types\/dotnet"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/users\/553"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/comments?post=499891"}],"version-history":[{"count":9,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/dotnet\/499891\/revisions"}],"predecessor-version":[{"id":508373,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/dotnet\/499891\/revisions\/508373"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/media\/500154"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/media?parent=499891"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/categories?post=499891"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/tags?post=499891"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/cross-post-tag?post=499891"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}