Learn about the latest .NET Productivity features

Mika Dumont


The .NET Productivity team (a.k.a. Roslyn) is constantly thinking of new ways to make .NET developers more productive. We’ve been working hard to take the feedback you’ve sent us and turn it into tools that you want! In this post, I’ll cover some of the latest .NET productivity features available in Visual Studio 2019.

Tooling improvements

The feature that I’m most excited about is the IntelliSense completion in DateTime and TimeSpan string literals. 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’ll then see completion options and an explanation as to what each character means.IntelliSense Completion DateTime TimeSpan

Add file header allows you to easily add file headers to existing files, projects, and solutions using EditorConfig. You’ll first need to add the file_header_template rule to your .editorconfig file. Then, set the value to equal the header text you’d like applied. Next, place your caret on the first line of any C# or Visual Basic file. Press (Ctrl+.) to trigger the Quick Actions and Refactorings menu and select Add file header.

Add File Header

The change method signature dialog now allows you to add a parameter. Place your caret within the method’s signature. Press (Ctrl+.) to trigger the Quick Actions and Refactorings menu and select Change signature. The following dialog will open where you can now select Add to add a parameter.

Change Signature

Once you select Add, the new Add Parameter dialog 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.

Add Parameter

Code fixes and refactorings

Code fixes and refactorings are the code suggestions the compiler provides through the light bulb and screwdriver icons. To trigger the Quick Actions and Refactorings menu, press (Ctrl+.) or (Alt+Enter). The following list shows the code fixes and refactorings that are new in Visual Studio 2019:

The add explicit cast code fix allows you to add an explicit cast when an expression cannot be implicitly cast. Place your caret on the error. Press (Ctrl+.) to trigger the Quick Actions and Refactorings menu and select Add explicit cast.

Add Explicit Cast

The simplify conditional expression refactoring simplifies conditional expressions to be more legible and concise. Place your caret on the conditional expression. Press (Ctrl+.) to trigger the Quick Actions and Refactorings menu and select Simplify conditional expression.

Simplify Conditional Expression

Have you ever wished you could easily read or convert to a verbatim string? Now you have a refactoring at your fingertips to convert between regular string and verbatim string literals. Place your caret on either the regular string or the verbatim string literal. Press (Ctrl+.) to trigger the Quick Actions and Refactorings menu. Next, select from one of the following:

Select Convert to verbatim string:

Convert To Verbatim String

Select Convert to regular string:

Convert To Regular String

The add debugger display attribute refactoring allows you to pin properties within the debugger programmatically in your code. Place your caret on the class name. Press (Ctrl+.) to trigger the Quick Actions and Refactorings menu and select Add ‘DebuggerDisplay’ attribute. 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.

Add Debugger Display Attribute

The generate comparison operators refactoring generates a boilerplate code with comparison operators for types that implement IComparable. Place your caret either inside the class or on IComparable. Press (Ctrl+.) to trigger the Quick Actions and Refactorings menu and select Generate comparison operators.

Generate Comparison Operators

The generate IEquatable operators refactoring automatically adds the IEquatable as well as the equals and not equals operators for structs. Place your caret within the struct. Press (Ctrl+.) to trigger the Quick Actions and Refactorings menu and select Generate Equals(object).

Generate IEquatable Operators

The generate properties when generating a constructor allows you to easily create a constructor with properties in a type. Place your caret on the instance. Press (Ctrl+.) to trigger the Quick Actions and Refactorings menu and select Select Generate constructor in <QualifiedName> (with properties).

Generate Properties With Constructor

There’s now an easy fix for accidental assignments and comparisons. Place your caret on the warning. Press (Ctrl+.) to trigger the Quick Actions and Refactorings menu. Next, select from one of the following options:

For accidental assignments, select Assign to ‘<QualifiedName>.value’:

Accidental Assignments

For accidental comparisons, select Compare to ‘<QualifiedName>.value’:

Accidental Comparison

The 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’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 (Ctrl+.) to trigger the Quick Actions and Refactorings menu. Next, select from one of the following:

To remove the operator completely, select Remove operator (preserves semantics):

Remove Suppression Operator

To negate the expression, select Negate expression (change semantics):

Negate Expression

Get involved

This was just a sneak peek of what’s new in Visual Studio 2019. For a complete list of what’s new, see the release notes. And feel free to provide feedback on the Developer Community website, or using the Report a Problem tool in Visual Studio.


Comments are closed. Login to edit/delete your existing comments

  • Avatar

    Refactorings are great.

    That said, what I’d really like to see is C# Interactive updated and hooked into the debugger so its a proper REPL environment while debugging.

    Right now C# REPL in Visual Studio is a mess. You have C# Interactive, which has been abandoned for several years, and was never able to participate in the debug session. And while debugging you have the Immediate Window which has been abandoned for decades and is very limited in what it can do.

    I’d also like to see the Visualizer API fixed and modernized so that the community can actually easily build visualizers like they build any other VS extension.

  • Avatar
    Homer Trune

    Hi friend. I would recommend that you turn to professionals who are well versed in this matter. I know that many owners of IT companies cooperate with https://alpacked.io/ , have you heard about such a company before? They provide a large package of services. Their team has many competent developers. I think you should visit the site that I dropped you. There is all the detailed information about their services and cost.

  • Avatar

    I have tried to get the “Add ‘DebuggerDisplay’ attribute” refactoring to work, but it never shows up in the context menu. I place my caret on the class name, press (Ctrl+.) to trigger the Quick Actions and Refactorings menu, and select Add ‘DebuggerDisplay’ attribute. This option does not appear. I am using Version 16.6.5 of Visual Studio Professional 2019.

    Any ideas why it is not working?

  • Avatar
    Marc Burns

    I’ve been quite enamored by the recent enhancements. The ML assisted package install for example, in a unit test

    var mockedObject = new Mock()

    will recommend installing Moq and adding a reference.

    This is fantastic for cognitive offloading, I.e. not having to remember so much “stuff”

  • Avatar
    Mike Wodarczyk

    Love It! I am not clear on how the equality and comparison code works (or doesn’t work) with c# 8’s nullability? I think that these methods work only with the non-nullable variables of a class. If I have a nullable ( CreateIEquatable? x ), would I have to have nullable versions of the equality methods? e.g. public bool Equals(CreateIEquatable? other) { … }

  • Avatar
    Jacob McDowell

    mini PSA: Loads of this (and other Roslyn & Editorconfig stuff) is also available in VS Code ! (And typically new stuff shows up sooner than in VS) It’s off by default but adding “omnisharp.enableEditorConfigSupport”: true and “omnisharp.enableRoslynAnalyzers”: true to your settings.json will “light up” Roslyn and “Code Styles.” By exporting your VS settings to an editorconfig file in your User Path or project/solution/repo folder, VS Code will enforce those same settings. https://docs.microsoft.com/en-us/visualstudio/ide/code-styles-and-code-cleanup?view=vs-2019

    Not trying to get anyone to switch or anything but that this stuff is opt-in is a bit of a peeve of mine, it should be more visible/discoverable at least ! Gives VS Code / C# Extension combo a poor first impression from my anecdotal reddit observations & newbie assistance. “Flip a switch” and stuff lights up: https://i.imgur.com/9lB4A2u.png / https://i.imgur.com/7xDgm5h.png See also: Roslynator 😃

  • Avatar
    Michele Picaro

    Lost 1 hour to understand why Now.ToString intellisense doesn’t work and, searching by myself in the future releases, I discover that is a 16.6/16.7 preview feature!
    You can’t write an article without all necessary reference like version that support announced functionality!
    Engeneers and developer works great but on communication and help you have a long way to go.

  • Avatar
    Jeff Jones

    I appreciate all the many items MS adds to VS that advance rapid application development (RAD). What sticks in my craw, is the absence of a great visual designer for Xamarin Forms (XAML) and Blazor (HTML). 30 years ago, Visual Basic developers had a Windows Forms designer that was so good, MS competitors copied the functionality. Both MS and the MS development community understood the value of RAD. When VB gave way to VS and .NET, the Windows Forms designer was updated, made even better, and provided the RAD features other IDEs lacked.

    Today, the concept of RAD seems to be lost on MS and today’s developers that perhaps never experienced the productivity of great RAD tools, and prefer hand-coding XAML and HTML to use a RAD visual designer so the time saved could be spent on making the app even better without loss of performance or capability.

    MS needs to put the resources into truly productive RAD visual designers for XAML and HTML on a par with the .NET framework Windows Forms designer (the one for .NET core isn’t anywhere close yet). When today’s “command line kiddies” experience the productivity gains from visual designers, they will be amazed.

    THAT is the most needed productivity feature – by far.

    Hint: A single generic designer can translate the UI objects it uses internally to the specific implementation (UWP XAML, XF XAML, HTML, WinForms, WPF), so only one designer exists instead of multiple ones.

    • Avatar

      Visual designers worked great when back in the day when we were dealing with absolutely sized, singular UI elements placed in grid coordinates. For modern UI frameworks, you create relative sized and relative positioned elements that are reactive and responsive to their display surface.

      Your HTML can define elements that have a completely different layout depending on whether you are viewing the page on a desktop monitor or on an iPhone. That’s all controlled by CSS & JS and I don’t see how you’re going to do that with a visual designer.

      WPF has “lookless” controls. You can redefine a control’s entire template to support scenarios that were just simply not possible with WinForms, like embedding controls into other controls. Styles can be defined in resource dictionaries and applied globally. More scenarios where visual designers are probably not a good fit.

      The fact is that we’ve moved into an era where UI is code and code is the easiest way to express UI.

      • Avatar
        Robert Plummer

        All limelight says is probably true, but I still agree with Jeff. The important word in his comment is “rapid”. If I am brainstorming some ideas and want to try out a few things, none of the situations mentioned occur. If an idea makes the cut, then I can think about those issues.

        This is not from “back in the day”–this is right now and I want to try something on my local machine. Fiddling with XAML is the last thing I want to do. A simple example: I have some “back-end” code that I want to try out, and I want to make a simple UI to do that. Or, I want to get the look and feel of a particular UI approach. If I can’t do this quickly and effortlessly, for several versions, then the world will pass me by.

        So thanks, Jeff for your comments, and please, ML, continue to put effort into good visual designers. To my mind, they are the essential starting point in new development efforts.