{"id":29049,"date":"2020-07-29T10:15:56","date_gmt":"2020-07-29T17:15:56","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/dotnet\/?p=29049"},"modified":"2020-07-28T15:43:44","modified_gmt":"2020-07-28T22:43:44","slug":"learn-about-the-latest-net-productivity-features","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/learn-about-the-latest-net-productivity-features\/","title":{"rendered":"Learn about the latest .NET Productivity features"},"content":{"rendered":"<div>The .NET Productivity team (a.k.a. Roslyn) is constantly thinking of new ways to make .NET developers more productive. We\u2019ve been working hard to take the feedback you\u2019ve sent us and turn it into tools that you want! 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>.<\/div>\n<p><br\/><\/p>\n<h3>Tooling\u00a0improvements<\/h3>\n<div><\/div>\n<div>The feature that I\u2019m most excited about is the <a href=\"https:\/\/docs.microsoft.com\/visualstudio\/ide\/reference\/datetime-timespan-completion\">IntelliSense completion in DateTime and TimeSpan string literals<\/a>. This feature is extremely helpful because we all know remembering DateTime and TimeSpan formats is hard enough. Place your caret inside the DateTime or TimeSpan string literal and press (Ctrl + Space). You&#8217;ll then see completion options and an explanation as to what each character means.<img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/07\/16.7_IntelliSense_Completion_DateTime_TimeSpan2.png\" alt=\"IntelliSense Completion DateTime TimeSpan\" width=\"1379\" height=\"257\" \/><\/div>\n<p><br\/><\/p>\n<p><a href=\"https:\/\/docs.microsoft.com\/visualstudio\/ide\/reference\/add-file-header\">Add file header<\/a> allows you to easily add file headers to existing files, projects, and solutions using <a href=\"https:\/\/docs.microsoft.com\/visualstudio\/ide\/create-portable-custom-editor-options#add-an-editorconfig-file-to-a-project\">EditorConfig<\/a>. You&#8217;ll first need to add the <em>file_header_template<\/em> rule to your <em>.editorconfig<\/em> file. Then, set the value to equal the header text you&#8217;d like applied. Next, place your caret on the first line of any C# or Visual Basic file. Press (<strong>Ctrl<\/strong>+<strong>.<\/strong>) to trigger the <strong>Quick Actions and Refactorings<\/strong> menu and select <strong>Add file header<\/strong>.<\/p>\n<div><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/07\/file-header.png\" alt=\"Add File Header\" width=\"1237\" height=\"406\" \/><\/div>\n<p><br\/><\/p>\n<p>The <a href=\"https:\/\/docs.microsoft.com\/visualstudio\/ide\/reference\/change-method-signature\">change method signature<\/a> dialog now allows you to add a parameter. Place your caret within the method\u2019s signature. Press (<strong>Ctrl<\/strong>+<strong>.<\/strong>) to trigger the <strong>Quick Actions and Refactorings<\/strong> menu and select <strong>Change signature<\/strong>. The following dialog will open where you can now select <strong>Add<\/strong> to add a parameter.<\/p>\n<div><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/07\/Change-Signature-Dialog.png\" alt=\"Change Signature\" width=\"1237\" height=\"884\" \/><\/div>\n<p><br\/>\nOnce you select <strong>Add<\/strong>, the new <strong>Add Parameter<\/strong>\u00a0dialog opens. The Add Parameter dialog allows you to add a type name and a parameter name. You can choose to make the parameter required or optional with a default value. You can then add a value at the call site and choose a named argument for that value or you can introduce a TODO variable. The TODO variable puts a TODO in your code so you can visit each error and go through each call site independently and decide what to pass. For optional parameters you have the option to omit the call site completely.<\/p>\n<div><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/07\/Add-Parameter-2.png\" alt=\"Add Parameter\" width=\"1169\" height=\"999\" \/><\/div>\n<p><br\/><\/p>\n<h3>Code\u00a0fixes\u00a0and\u00a0refactorings<\/h3>\n<div>\n<div>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:<\/div>\n<\/div>\n<p><br\/>\nThe <a href=\"https:\/\/docs.microsoft.com\/visualstudio\/ide\/reference\/add-explicit-cast\">add explicit cast<\/a> code fix allows you to add an explicit cast when an expression cannot be implicitly cast. Place your caret on the error. Press (<strong>Ctrl<\/strong>+<strong>.<\/strong>) to trigger the <strong>Quick Actions and Refactorings<\/strong> menu and select <strong>Add explicit cast<\/strong>.<\/p>\n<div><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/07\/Add-Explicit-Cast.png\" alt=\"Add Explicit Cast\" width=\"1299\" height=\"525\" \/><\/div>\n<p><br\/>\nThe <a href=\"https:\/\/docs.microsoft.com\/visualstudio\/ide\/reference\/simplify-conditional-expression\">simplify conditional expression<\/a> refactoring simplifies conditional expressions to be more legible and concise. Place your caret on the conditional expression. Press (<strong>Ctrl<\/strong>+<strong>.<\/strong>) to trigger the <strong>Quick Actions and Refactorings<\/strong> menu and select <strong>Simplify conditional expression<\/strong>.<\/p>\n<div><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/07\/Simplify-Conditional-Expression.png\" alt=\"Simplify Conditional Expression\" width=\"1286\" height=\"489\" \/><\/div>\n<p><br\/>\nHave you ever wished you could easily read or convert to a verbatim string? Now you have a refactoring at your fingertips to <a href=\"https:\/\/docs.microsoft.com\/visualstudio\/ide\/reference\/convert-between-regular-string-verbatim-string\">convert between regular string and verbatim string literals<\/a>. Place your caret on either the regular string or the verbatim string literal. Press (<strong>Ctrl<\/strong>+<strong>.<\/strong>) to trigger the <strong>Quick Actions and Refactorings<\/strong> menu. Next, select from one of the following:<br\/><\/p>\n<div><\/div>\n<p>Select <strong>Convert to verbatim string<\/strong>:<\/p>\n<div><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/07\/Convert-To-Verbatim-String.png\" alt=\"Convert To Verbatim String\" width=\"1886\" height=\"597\" \/><\/div>\n<p><br\/>\nSelect <strong>Convert to regular string<\/strong>:<\/p>\n<div><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/07\/Convert-To-Regular-String.png\" alt=\"Convert To Regular String\" width=\"1766\" height=\"577\" \/><\/div>\n<p><br\/>\nThe <a href=\"https:\/\/docs.microsoft.com\/visualstudio\/ide\/reference\/add-debugger-display-attribute\">add debugger display attribute<\/a> refactoring allows you to pin properties within the debugger programmatically in your code. Place your caret on the class name. Press (<strong>Ctrl<\/strong>+<strong>.<\/strong>) to trigger the <strong>Quick Actions and Refactorings<\/strong> menu and select <strong>Add &#8216;DebuggerDisplay&#8217; attribute<\/strong>. This will add the debugger display attribute to the top of your class and generate an auto method that returns ToString(), which you can edit to return the property value you want pinned in the debugger.<\/p>\n<div><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/07\/Add-Debugger-Display-Attribute.png\" alt=\"Add Debugger Display Attribute\" width=\"1777\" height=\"771\" \/><\/div>\n<p><br\/>\nThe <a href=\"https:\/\/docs.microsoft.com\/visualstudio\/ide\/reference\/generate-comparison-operators\">generate comparison operators<\/a> refactoring generates a boilerplate code with comparison operators for types that implement IComparable. Place your caret either inside the class or on IComparable. Press (<strong>Ctrl<\/strong>+<strong>.<\/strong>) to trigger the <strong>Quick Actions and Refactorings<\/strong> menu and select <strong>Generate comparison operators<\/strong>.<\/p>\n<div><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/07\/Generate-Comparison-Operators.png\" alt=\"Generate Comparison Operators\" width=\"1882\" height=\"954\" \/><\/div>\n<p><br\/>\nThe <a href=\"https:\/\/docs.microsoft.com\/visualstudio\/ide\/reference\/generate-equals-structs\">generate IEquatable operators<\/a> refactoring automatically adds the IEquatable as well as the equals and not equals operators for structs. Place your caret within the struct. Press (<strong>Ctrl<\/strong>+<strong>.<\/strong>) to trigger the <strong>Quick Actions and Refactorings<\/strong> menu and select <strong>Generate Equals(object)<\/strong>.<\/p>\n<div><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/07\/Generate-IEquatable-Operators.png\" alt=\"Generate IEquatable Operators\" width=\"1861\" height=\"1018\" \/><\/div>\n<p><br\/>\nThe <a href=\"https:\/\/docs.microsoft.com\/visualstudio\/ide\/reference\/generate-constructor#-generate-constructor-with-properties-c-only\">generate properties when generating a constructor<\/a> allows you to easily create a constructor with properties in a type. Place your caret on the instance. Press (<strong>Ctrl<\/strong>+<strong>.<\/strong>) to trigger the <strong>Quick Actions and Refactorings<\/strong> menu and select Select <strong>Generate constructor in &lt;QualifiedName&gt; (with properties)<\/strong>.<\/p>\n<div><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/07\/Generate-Properties-With-Constructor.png\" alt=\"Generate Properties With Constructor\" width=\"1524\" height=\"640\" \/><\/div>\n<p><br\/>\nThere&#8217;s now an easy fix for accidental assignments and comparisons. Place your caret on the warning. Press (<strong>Ctrl<\/strong>+<strong>.<\/strong>) to trigger the <strong>Quick Actions and Refactorings<\/strong> menu. Next, select from one of the following options:<br\/><\/p>\n<div><\/div>\n<p>For accidental assignments, select <strong>Assign to &#8216;&lt;QualifiedName&gt;.value&#8217;<\/strong>:<\/p>\n<div><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/07\/Accidental-Assignments.png\" alt=\"Accidental Assignments\" width=\"1279\" height=\"567\" \/><\/div>\n<p><br\/>\nFor accidental comparisons, select <strong>Compare to &#8216;&lt;QualifiedName&gt;.value&#8217;<\/strong>:<\/p>\n<div><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/07\/Accidental-Comparisons2.png\" alt=\"Accidental Comparison\" width=\"1275\" height=\"573\" \/><\/div>\n<p><br\/>\nThe null suppression operator warning and code fix helps you to easily identify and fix a suppression operator that has no effect. For example, in this case someone wanted to express that something isn&#8217;t `string` and typed `!is string` instead of `is not string`. The `!` is legal but is interpreted as asserting the expression on the left as is not `null`. Since that can be confusing, we now offer a warning and code fix. Place your caret on the suppression operator. Press (<strong>Ctrl<\/strong>+<strong>.<\/strong>) to trigger the <strong>Quick Actions and Refactorings<\/strong>\u00a0menu. Next, select from one of the following:<br\/><\/p>\n<div><\/div>\n<p>To remove the operator completely, select <strong>Remove operator (preserves semantics)<\/strong>:<\/p>\n<div><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2022\/08\/Remove-Suppression-Operator-2.png\" alt=\"Remove Suppression Operator\" width=\"1381\" height=\"486\" class=\"aligncenter size-full wp-image-29097\" srcset=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2022\/08\/Remove-Suppression-Operator-2.png 1381w, https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2022\/08\/Remove-Suppression-Operator-2-300x106.png 300w, https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2022\/08\/Remove-Suppression-Operator-2-1024x360.png 1024w, https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2022\/08\/Remove-Suppression-Operator-2-768x270.png 768w\" sizes=\"(max-width: 1381px) 100vw, 1381px\" \/><\/div>\n<p><br\/>\nTo negate the expression, select <strong>Negate expression (change semantics)<\/strong>:<\/p>\n<div><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2022\/08\/Negate-Expression-2.png\" alt=\"Negate Expression\" width=\"1370\" height=\"489\" class=\"aligncenter size-full wp-image-29098\" srcset=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2022\/08\/Negate-Expression-2.png 1370w, https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2022\/08\/Negate-Expression-2-300x107.png 300w, https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2022\/08\/Negate-Expression-2-1024x366.png 1024w, https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2022\/08\/Negate-Expression-2-768x274.png 768w\" sizes=\"(max-width: 1370px) 100vw, 1370px\" \/><\/div>\n<p><br\/><\/p>\n<h3>Get involved<\/h3>\n<div>\n<div>\n<div>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.<\/div>\n<\/div>\n<\/div>\n<div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>The .NET Productivity team (a.k.a. Roslyn) is constantly thinking of new ways to make .NET developers more productive. We\u2019ve been working hard to take the feedback you\u2019ve sent us and turn it into tools that you want! In this post, I\u2019ll cover some of the latest .NET productivity features available in Visual Studio 2019. Tooling\u00a0improvements [&hellip;]<\/p>\n","protected":false},"author":5818,"featured_media":58792,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[685],"tags":[],"class_list":["post-29049","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet"],"acf":[],"blog_post_summary":"<p>The .NET Productivity team (a.k.a. Roslyn) is constantly thinking of new ways to make .NET developers more productive. We\u2019ve been working hard to take the feedback you\u2019ve sent us and turn it into tools that you want! In this post, I\u2019ll cover some of the latest .NET productivity features available in Visual Studio 2019. Tooling\u00a0improvements [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/29049","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=29049"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/29049\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/58792"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=29049"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=29049"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=29049"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}