{"id":30769,"date":"2020-11-18T10:05:41","date_gmt":"2020-11-18T17:05:41","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/dotnet\/?p=30769"},"modified":"2020-11-17T13:25:13","modified_gmt":"2020-11-17T20:25:13","slug":"whats-new-in-net-productivity","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/whats-new-in-net-productivity\/","title":{"rendered":"What&#8217;s new in .NET Productivity"},"content":{"rendered":"<p>The .NET Productivity team (a.k.a. Roslyn) wants to help you be more productive! We\u2019ve seen a lot of excitement in the past few months over our latest features which automate and reduce editing tasks to a single click and help save you time. In this post, I\u2019ll cover some of the latest .NET productivity features available in <a href=\"https:\/\/visualstudio.microsoft.com\/downloads\/\">Visual Studio 2019<\/a>.<\/p>\n<h2>Tooling improvements<\/h2>\n<p>Starting in .NET 5.0, Roslyn analyzers are included with the <a href=\"https:\/\/docs.microsoft.com\/dotnet\/fundamentals\/code-analysis\/overview\">.NET SDK<\/a>. Roslyn analyzers are enabled, by default, for projects that target .NET 5.0 or later. You can enable them on projects that target earlier .NET versions by setting the <a href=\"https:\/\/docs.microsoft.com\/dotnet\/core\/project-sdk\/msbuild-props#enablenetanalyzers\">EnableNETAnalyzers<\/a> property to <em>true<\/em>. You can also use the Project Properties to enable\/disable .NET analyzers. To access the Project Properties, right-click on a project within Solution Explorer and select Properties. Next, select the Code Analysis tab where you can either select or clear the checkbox to Enable .NET analyzers.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/11\/code_analysis_project_properties.png\" alt=\"Project Properties dialog to enforce .NET 5.0 Analyzers\" \/><\/p>\n<p>Another exciting feature is <a href=\"https:\/\/docs.microsoft.com\/visualstudio\/ide\/reference\/options-text-editor-csharp-advanced?view=vs-2019#editor-help\">inline parameter name hints<\/a> that inserts adornments for literals, casted literals, and object instantiations prior to each argument in function calls. In 16.9 Preview 1, we also added inline type hints for variables with inferred types and lambda parameter types. You\u2019ll first need to turn this option on in <em>Tools<\/em> &gt; <em>Options<\/em> &gt; <em>Text Editor<\/em> &gt; <em>C#<\/em> or <em>Basic<\/em> &gt; <em>Advanced<\/em> and select <strong>Display inline parameter name hints<\/strong> and <strong>Display inline type hints<\/strong>. You can also use the shortcut <strong>Alt<\/strong>+<strong>F1<\/strong> to briefly view hints.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/11\/inline_hints.gif\" alt=\"Inline Hints\" \/><\/p>\n<p>You can now extract members from a selected class to\u202fa\u202fnew base class with the new\u202f<a href=\"https:\/\/docs.microsoft.com\/visualstudio\/ide\/reference\/extract-base-class?view=vs-2019\" rel=\"noopener noreferrer\" target=\"_blank\">extract base class<\/a>\u202frefactoring.\u202fPlace your cursor on either the class name or a highlighted member. Press <strong>Ctrl<\/strong>+<strong>.<\/strong> to trigger the <strong>Quick Actions and Refactorings<\/strong> menu. Select\u202f<strong>Pull member(s) up to new base class<\/strong> or <strong>Extract base class<\/strong>.\u202fThe\u202fnew\u202f<strong>Extract\u202fBase\u202fClass<\/strong>\u202fdialog will open where you can specify the name for the base class and location of where it should be placed. You can select the members that you want to transfer to the new base class and choose to make the members abstract by selecting the checkbox in the\u202f<strong>Make\u202fabstract<\/strong>\u202fcolumn.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/11\/extract_base_class.png\" alt=\"Extract Base Class dialog\" \/><\/p>\n<p><a href=\"https:\/\/docs.microsoft.com\/visualstudio\/ide\/code-styles-and-code-cleanup?view=vs-2019#apply-code-styles\">Code cleanup<\/a> has new configuration options that can apply formatting and file header preferences set in your <a href=\"https:\/\/docs.microsoft.com\/visualstudio\/ide\/create-portable-custom-editor-options?view=vs-2019#add-an-editorconfig-file-to-a-project\">EditorConfig<\/a> file across a single file or an entire solution.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/11\/code_cleanup_format_header.png\" alt=\"Code Cleanup dialog\" \/><\/p>\n<h2>Code fixes and refactorings<\/h2>\n<p>Code fixes and refactorings are the code suggestions the compiler provides through the light bulb and screwdriver icons. To trigger the <strong>Quick Actions and Refactorings<\/strong> menu, press (<strong>Ctrl<\/strong>+<strong>.<\/strong>) or (<strong>Alt<\/strong>+<strong>Enter<\/strong>). The following list shows the code fixes and refactorings that are new in Visual Studio 2019:<\/p>\n<p>The <a href=\"https:\/\/docs.microsoft.com\/visualstudio\/ide\/reference\/inline-method?view=vs-2019\">inline method<\/a> refactoring helps you replace usages of a static, instance, and extension method within a single statement body with an option to remove the original method declaration. Place your cursor on the usage of the method. Press <strong>Ctrl<\/strong>+<strong>.<\/strong> to trigger the <strong>Quick Actions and Refactorings<\/strong> menu. Next select from one of the following options:<\/p>\n<p>Select <strong>Inline <code>&lt;QualifiedMethodName&gt;<\/code><\/strong> to remove the inline method declaration:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/11\/inline_method_remove_declaration.png\" alt=\"Inline method refactoring removing method declaration\" \/><\/p>\n<p>Select <strong>Inline and keep <code>&lt;QualifiedMethodName&gt;<\/code><\/strong> to preserve the original method declaration:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/11\/inline_method_preserve_declaration.png\" alt=\"Inline method refactoring preserving method declaration\" \/><\/p>\n<p>The <a href=\"https:\/\/docs.microsoft.com\/visualstudio\/ide\/reference\/use-pattern-matching?view=vs-2019\">use pattern matching<\/a> refactoring introduces the new C# 9 pattern combinators. Along with the pattern matching suggestions, such as converting <code>==<\/code> to use <code>is<\/code> where applicable, this code fix also suggests the pattern combinators <code>and<\/code>, <code>or<\/code> and <code>not<\/code> when matching multiple different patterns and negating. Place your cursor inside the statement. Press <strong>Ctrl<\/strong>+<strong>.<\/strong> to trigger the <strong>Quick Actions and Refactorings<\/strong> menu and select <strong>Use pattern matching<\/strong>.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/11\/use_pattern_matching_not_syntax.png\" alt=\"Use pattern matching refactoring\" \/><\/p>\n<p>The <a href=\"https:\/\/docs.microsoft.com\/visualstudio\/ide\/reference\/make-class-abstract?view=vs-2019\">make class abstract<\/a> refactoring allows you to easily make a class abstract when you\u2019re trying to write an abstract method in a class that isn\u2019t abstract. Place your cursor on the method error. Press <strong>Ctrl<\/strong>+<strong>.<\/strong> to trigger the <strong>Quick Actions and Refactorings<\/strong> menu and select <strong>Make class \u2018abstract\u2019<\/strong>.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/11\/make_class_abstract2.png\" alt=\"Make class abstract refactoring\" \/><\/p>\n<p>The convert <a href=\"https:\/\/docs.microsoft.com\/visualstudio\/ide\/reference\/convert-typeof-to-nameof?view=vs-2019\">typeof to nameof<\/a> refactoring allows you to easily convert instances of <em>typeof(<code>&lt;QualifiedType&gt;<\/code>).Name<\/em> to <em>nameof(<code>&lt;QualifiedType&gt;<\/code>)<\/em> in C# and instances of <em>GetType(<code>&lt;QualifiedType&gt;<\/code>).Name<\/em> to <em>NameOf(<code>&lt;QualifiedType&gt;<\/code>)<\/em> in Visual Basic. Using <em>nameof<\/em> instead of the name of the type avoids the reflections involved when retrieving an object. Place your cursor within the <em>typeof(<code>&lt;QualifiedType&gt;<\/code>).Name<\/em>. Press <strong>Ctrl<\/strong>+<strong>.<\/strong> to trigger the <strong>Quick Actions and Refactorings<\/strong> menu and select\u202f<strong>Convert\u202f&#8217;typeof&#8217;\u202fto\u202f&#8217;nameof&#8217;<\/strong>.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/11\/convert_typeof_nameof_csharp.png\" alt=\"Convert typeof to nameof refactoring\" \/><\/p>\n<p>Visual Basic had multiple ways of passing parameters, <em>ByVal<\/em> and <em>ByRef<\/em>, and for a long time <em>ByVal<\/em> has been optional. We now fade <em>ByVal<\/em> to say it&#8217;s not necessary along with a code fix to remove the unnecessary <em>ByVal<\/em>. Place your cursor on the ByVal keyword. Press <strong>Ctrl<\/strong>+<strong>.<\/strong> to trigger the <strong>Quick Actions and Refactorings<\/strong> menu and select <strong>\u2018ByVal\u2019 keyword is unnecessary and can be removed<\/strong>.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/11\/remove_byval.png\" alt=\"Remove unnecessary ByVal keyword\" \/><\/p>\n<p>Now, there\u2019s also a code fix to remove the <code>in<\/code> keyword where the argument shouldn\u2019t be passed by reference. Place your cursor on the error. Press <strong>Ctrl<\/strong>+<strong>.<\/strong> to trigger the <strong>Quick Actions and Refactorings<\/strong> menu and select <strong>Remove \u2018in\u2019 keyword<\/strong>.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/11\/remove_in_keyword.png\" alt=\"Remove in keyword\" \/><\/p>\n<p>In 16.9 Preview 1, we also added a code fix that removes redundant equality expressions for both C# and Visual Basic. Place your cursor on the redundant equality expression. Press <strong>Ctrl<\/strong>+<strong>.<\/strong> to trigger the <strong>Quick Actions and Refactorings<\/strong> menu and select <strong>Remove redundant equality<\/strong>.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/11\/remove_redundant_equality_operator.png\" alt=\"Remove redundant equality\" \/><\/p>\n<p>And the last refactoring we added in 16.9 Preview 1 suggests <a href=\"https:\/\/docs.microsoft.com\/visualstudio\/ide\/reference\/use-new?view=vs-2019\">using \u2018new(\u2026)\u2019<\/a> in non-contentious scenarios. Place your cursor on the field declaration. Press <strong>Ctrl<\/strong>+<strong>.<\/strong> to trigger the <strong>Quick Actions and Refactorings<\/strong> menu and select <strong>Use &#8216;new(\u2026)&#8217;<\/strong>.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/11\/use-new.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-30773\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/11\/use-new.png\" alt=\"Use new() refactoring\" width=\"1558\" height=\"533\" srcset=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/11\/use-new.png 1558w, https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/11\/use-new-300x103.png 300w, https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/11\/use-new-1024x350.png 1024w, https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/11\/use-new-768x263.png 768w, https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/11\/use-new-1536x525.png 1536w\" sizes=\"(max-width: 1558px) 100vw, 1558px\" \/><\/a><\/p>\n<h2>Get involved<\/h2>\n<p>This was just a sneak peek of what&#8217;s new in <a href=\"https:\/\/visualstudio.microsoft.com\/downloads\/\">Visual Studio 2019<\/a>. For a complete list of what&#8217;s new, see the <a href=\"https:\/\/docs.microsoft.com\/visualstudio\/releases\/2019\/release-notes\">release notes<\/a>. And feel free to provide feedback on the <a href=\"https:\/\/developercommunity.visualstudio.com\/spaces\/8\/index.html\">Developer Community<\/a> website, or using the <a href=\"https:\/\/docs.microsoft.com\/visualstudio\/ide\/how-to-report-a-problem-with-visual-studio\">Report a Problem<\/a> tool in Visual Studio. You can also share your feedback with us on <a href=\"https:\/\/github.com\/dotnet\/roslyn\/issues\">GitHub<\/a> or tweet @roslyn, we&#8217;d love to hear what you think!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Learn about the latest .NET Productivity features!<\/p>\n","protected":false},"author":5818,"featured_media":30773,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[685,196,756,646],"tags":[4,7198,311,316,7197],"class_list":["post-30769","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet","category-dotnet-core","category-csharp","category-visual-studio","tag-net","tag-net-5-0","tag-code-fixes","tag-refactoring","tag-tooling-improvements"],"acf":[],"blog_post_summary":"<p>Learn about the latest .NET Productivity features!<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/30769","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/5818"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=30769"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/30769\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/30773"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=30769"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=30769"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=30769"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}