{"id":371615,"date":"2023-07-14T14:52:41","date_gmt":"2023-07-14T13:52:41","guid":{"rendered":"https:\/\/blog.jetbrains.com\/?post_type=dotnet&#038;p=371615"},"modified":"2025-09-17T14:21:38","modified_gmt":"2025-09-17T13:21:38","slug":"rsrp-rider-2023-2-eap9","status":"publish","type":"dotnet","link":"https:\/\/blog.jetbrains.com\/en\/dotnet\/2023\/07\/14\/rsrp-rider-2023-2-eap9","title":{"rendered":"Extended C# Support in ReSharper and Rider 2023.2 EAP 9"},"content":{"rendered":"\n<p>We\u2019ve just published new EAP builds for both <a href=\"https:\/\/www.jetbrains.com\/resharper\/nextversion\/#section=windows\" target=\"_blank\" rel=\"noopener\">ReSharper 2023.2<\/a> and <a href=\"https:\/\/www.jetbrains.com\/rider\/nextversion\/\" target=\"_blank\" rel=\"noopener\">Rider 2023.2<\/a>. Both contain updates to C# support. Let\u2019s dive in!&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">C#12 preview support&nbsp;<\/h2>\n\n\n\n<h4 class=\"wp-block-heading\">Primary constructors&nbsp;<\/h4>\n\n\n\n<p>In the 2023.2 version, we introduced primary constructor support for non-<code>record<\/code> <code>classes<\/code> and <code>structs<\/code> from the C# 12 preview. Unlike primary constructors in <code>records<\/code>, primary constructors in <code>classes<\/code> and <code>structs<\/code> do not implicitly declare members such as properties or fields. Instead, you can use the primary constructor parameters all over the type declaration. The compiler will figure out how to make the parameter value available in the context of usage. This may greatly reduce the amount of code repetitions.<\/p>\n\n\n\n<img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/07\/rd-cs-primary-constructor-parameters.png\" alt=\"\" width=\"900\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/07\/rd-cs-primary-constructor-parameters.gif\">\n\n\n\n<p>While the ability to make use of primary parameters in all instance members of type declarations is powerful, some of you may find this implicit &#8220;capture&#8221; of primary parameters into a type&#8217;s state a bit confusing. To make things more intuitive, we introduced additional coloring for &#8220;captured&#8221; primary constructor parameters. The default color is now the same as the ordinary fields\u2019 colors. As a result, it helps you easily differentiate ordinary method parameters from primary constructor parameters in the parameter list of the type.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/QUt0DdBDXweFIEDC6ZfHE6BrLZkLPyoO6uVa1MB18pCmLu9G0JaF_h5Y9lZYj8WmfsgMKvZh_5EnzWmqlU4KcHYfpv8hF4nHlXgzi7SU0r-JxgUrIUc-dmuCvvi4LVPsnqTsD6yWWXCVj32j1PXnJwg.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>The ReSharper and Rider 2023.2 EAP builds can now detect those types where the initialization can be expressed with new primary constructors. It can also suggest if private fields may be completely replaced by the use of primary constructor parameters. C# 12 now also supports the ability to add attributes for primary constructors (in <code>class<\/code>, <code>record<\/code><em>,<\/em> and <code>struct<\/code>) by using the <code><em>method<\/em>:<\/code> attribute target. The corresponding quick-fix to use the primary constructor will handle everything for you.<\/p>\n\n\n\n<img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/07\/rs-cs-primary-consctructors-private-fields.png\" alt=\"\" width=\"900\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/07\/rs-cs-primary-consctructors-private-fields.gif\">\n\n\n\n<p>Sometimes, the initialization of the type must be made less trivial and can no longer be expressed using a primary constructor. For such cases, we introduced context actions to convert the C# 12 primary constructors back to ordinary ones.&nbsp;<\/p>\n\n\n\n<img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/07\/rs-cs-primary-consctructors-parameters-reverse.png\" alt=\"\" width=\"900\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/07\/rs-cs-primary-consctructors-parameters-reverse.gif\">\n\n\n\n<p>As usual, you can also do a reverse replacement from primary constructor parameters to ordinary fields if you need to make a captured state available for derived classes with protected fields or if you need to annotate a field with an attribute.<\/p>\n\n\n\n<img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/07\/rd-cs-primary-consctructors-private-fields-reverse.png\" alt=\"\" width=\"900\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/07\/rd-cs-primary-consctructors-private-fields-reverse.gif\">\n\n\n\n<h4 class=\"wp-block-heading\">Other updates<\/h4>\n\n\n\n<p>Besides the primary constructors for non-<code>record<\/code> <code>classes<\/code> and <code>structs<\/code>, we added support for one more feature from the C# 12 preview. <\/p>\n\n\n\n<p>You can now use <code>;<\/code> instead of the empty<em> <\/em><code>{ }<\/code> block for type declarations for <code>class<\/code>, <code>struct<\/code>, <code>interface<\/code><em>,<\/em> and even <code>enum<\/code> declarations. The ReSharper and Rider 2023.2 EAP builds suggest you use this new syntax. You can then apply the quick-fix for different scopes including file, folder, project, and the entire solution.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/xJz2KkXwlSwoMAosk14BdCBlj2njtof_HouORGtU9-GEE6KvwlizNHB4xrHVxyBz3pHtJQe0EAt6tiC0QjsxOi0N60DmjCsZQrcuOFHp8BTilCk2crDwKAsmJB73M16mjCSddseNw350IQTUvCfSPtE.png\" alt=\"\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Support for the <code>IAsyncDisposable<\/code> interface&nbsp;<\/h2>\n\n\n\n<p>In addition to a few inspections to catch an early disposal of <code>using<\/code> variables, which we introduced in <a href=\"https:\/\/blog.jetbrains.com\/en\/dotnet\/2023\/06\/16\/resharper-2023-2-eap-5\">the EAP 5 build<\/a>, we improved the <em>Generate dispose pattern<\/em> feature to support the <code>IAsyncDisposable<\/code> interface and be able to generate an async method to release the resources.<\/p>\n\n\n\n<img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/07\/rd-cs-IAsyncDisposable.png\" alt=\"\" width=\"900\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/07\/rd-cs-IAsyncDisposable.gif\">\n\n\n\n<h2 class=\"wp-block-heading\">Better C# discards support&nbsp;<\/h2>\n\n\n\n<p>Both ReSharper and Rider 2023.2 EAPs received a bunch of new useful additions to C# discard support. As you may know, discards are placeholder variables that are intentionally unused in application code.<\/p>\n\n\n\n<p>You can now quickly check names and types of discarded values with <em>Push-to-Hint<\/em> functionality. Press and hold the <kbd>Ctrl<\/kbd><em> <\/em>key to activate the <em>Push-to-hint<\/em> mode.&nbsp;<\/p>\n\n\n\n<img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/07\/rd-cs-discard-push-to-hint.png\" alt=\"\" width=\"900\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/07\/rd-cs-discard-push-to-hint.gif\">\n\n\n\n<p>Since <code>_<\/code> is a valid name of an identifier in C#, we introduced some inspections to reduce the possibility of confusing <code>_<\/code> as a discard symbol. It can prepare your code for <a href=\"https:\/\/github.com\/dotnet\/csharplang\/discussions\/7033\" target=\"_blank\" rel=\"noopener\">upcoming breaking changes<\/a> in C#.<\/p>\n\n\n\n<p>There is now a warning about variables and parameters named <code>_<\/code> that are actually being used. They look like a &#8220;discarded&#8221; value, but in reality, they represent very much the opposite. To clarify the code, we now offer the quick-fix to rename the lambda parameter.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"900\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/07\/rd-cs-not-discard-variable.png\" alt=\"\" class=\"wp-image-372401\"\/><\/figure>\n\n\n\n<p>Also, we detect older code patterns that existed before the discard assignment was introduced in C# and offer the quick-fix \u2013 <em>Use discard assignment \u2013<\/em> to rewrite the code in a more idiomatic way using discards.<\/p>\n\n\n\n<img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/07\/rs-cs-discard-assignment.png\" alt=\"\" width=\"900\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/07\/rs-cs-discard-assignment.gif\">\n\n\n\n<p>That\u2019s it for today! <\/p>\n\n\n\n<p>The full list of improvements and fixes can be found on YouTrack:<\/p>\n\n\n\n<ul>\n<li><a href=\"https:\/\/youtrack.jetbrains.com\/issues?q=project:%20%7BRSRP%7D%20and%20available%20in:%20%7B2023.2%20EAP%209%7D%20\" target=\"_blank\" rel=\"noopener\">ReSharper 2023.2 EAP 9<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/youtrack.jetbrains.com\/issues?q=project:%20%7BRider%7D%20and%20available%20in:%20%7B2023.2%20EAP%209*%7D%20\" target=\"_blank\" rel=\"noopener\">Rider 2023.2 EAP 9<\/a><\/li>\n<\/ul>\n\n\n\n<p>If you have something to share with us, don\u2019t hesitate to let us know in the comments section below.<\/p>\n","protected":false},"author":1337,"featured_media":366702,"comment_status":"closed","ping_status":"closed","template":"","categories":[4992,89,907,3990,4140],"tags":[8126,600,8187,46,1978],"cross-post-tag":[],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/dotnet\/371615"}],"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\/1337"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/comments?post=371615"}],"version-history":[{"count":10,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/dotnet\/371615\/revisions"}],"predecessor-version":[{"id":624447,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/dotnet\/371615\/revisions\/624447"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/media\/366702"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/media?parent=371615"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/categories?post=371615"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/tags?post=371615"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/cross-post-tag?post=371615"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}