Learn What’s New in .NET Productivity

Mika Dumont

The .NET Productivity team (aka. Roslyn) continues to enhance your developer productivity with the latest tooling updates in Visual Studio 2019. In the last release, we listened to your feedback and have been hard at work improving the .NET developer experience. To try out the latest .NET productivity enhancements download the latest Visual Studio release.

Tooling improvements

The feature that I’m most excited about is Inheritance margin. Inheritance margin provides a visual representation for navigating and inspecting the inheritance chain. Inheritance margin is off by default, so you’ll need to enable it in Tools > Options > Text Editor > C# or Basic > Advanced and select Show inheritance margin. Enabling inheritance margin will add new icons to the margins representing your code’s implementations and overrides. Clicking on the inheritance margin icon will display inheritance options that you can select to navigate to.

Inheritance Margin

Another exciting feature is the new Remove Unused References command. This command allows you to clean up project references and NuGet packages that have no usage. Removing project references that have no usage can help save space, reduce startup time of your application, and make NuGet restore faster. The Remove Unused References command will appear in the right-click menu of a project name or dependencies node in Solution Explorer.

Remove Unused References command

When you select Remove Unused References, a dialog box will open where you can view all references that are going to be removed, but you also have the option to preserve any you wish to keep.

Remove Unused References dialog

EditorConfig files are a great way to define consistent code style and code quality preferences in your codebase. We received feedback that the configuration process wasn’t easy, so in 16.10 Preview 2 we added an EditorConfig designer allowing you to easily view and configure your code analysis preferences. To use the new designer, open any C# or Visual Basic EditorConfig file from your solution. The EditorConfig designer will display code analysis options for formatting, code style, third-party analyzers (i.e. if you have StyleCop or xUnit installed), and .NET code quality analyzers which we now include in the .NET 5.0 SDK. There is also an option to switch back to the EditorConfig text view by pressing F7.

EditorConfig designer

There’s a new command in town called Smart Break Line that automatically inserts a set of braces and places the caret within those braces when using Shift+Enter as a commit character. Smart Break Line works for all type declarations that require braces as well as properties, events, fields, and object creation expressions.

Smart Break Line

Using directives will now automatically get added when copying and pasting types to a new file. You’ll first need to turn this option on in Tools > Options > Text Editor > C# or Basic > Advanced and select Add missing using directives on paste.

Add missing usings on paste

Go To will no longer display duplicate results across .NET Core 2.0 and 3.1 apps as well as results for partial types that exist only to wrap another nested type. This will help declutter the results so you can easily find and navigate to code. The results also now include the filename for partial symbols.

Go To dialog

Edit and Continue (EnC) allows you to make changes to your source code during a debugging session while you’re in break mode, instead of having to stop, recompile your entire program, and restart the debugging session. Edit and Continue has some limitations, so not every edit is supported but in 16.10, we added support for editing partial classes, records, and add missing using directives. Edit and Continue also powers Hot Reload, which you can learn more about in the Introducing .NET Hot Reload blog!

IntelliSense completion

IntelliSense is a context-aware code completion feature that speeds up the process of coding applications by reducing typos and other common mistakes.

In 16.10 we added a completion option that automatically inserts arguments when writing a method call. This feature is off by default, so you’ll need to enable it in Tools > Options > Text Editor > C# > IntelliSense and select Tab twice to insert arguments (experimental). To use this feature, start writing a method call and press tab twice.

Method call argument completion

Notice that the method call includes arguments based on the method’s default values. Use parameter info to cycle through the list of arguments that you would like inserted by pressing the up and down arrow keys. Type semicolon, which will commit the arguments and add a semicolon to the end of the method call.

In 16.9 we added IntelliSense completion for Enum values when a type is known even if the Enum name is not entered. We decided to take this feature a step further by adding IntelliSense completion for casts, indexers, and operators.

IntelliSense completion for indexers

We also recently added IntelliSense completion for preprocessor symbols. Start typing the #if directive and notice the new completion options for symbols that are currently defined in scope.

Preprocessor symbols completion

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). In case you missed it we added some exciting new code fixes and refactorings!

The Simplify LINQ expressions refactoring will remove the unnecessary call to the Enumerable for the .Where() method to help improve performance and readability. Place your cursor on the LINQ expression. Press (Ctrl+.) to trigger the Quick Actions and Refactorings menu. Select Simplify LINQ expression.

Simplify LINQ expression

Remove extra white space in a document with the new Remove extra blank lines code fix. Place your cursor on an extra blank line. Press (Ctrl+.) to trigger the Quick Actions and Refactorings menu. Select Remove extra blank lines.

Remove extra blank lines

In C# 9.0, discards are unnecessary in certain pattern matching cases. We now fade unnecessary discards and offer a code fix to remove them. Place your cursor on the faded discard. Press (Ctrl+.) to trigger the Quick Actions and Refactorings menu. Select Remove unnecessary discard.

Remove unnecessary discard

Razor tooling

In 16.7 Preview 4, we added the new Razor editor for local development with MVC, Razor Pages, and Blazor. The new Razor editor has a ton of new tooling support surpassing the functionality of the existing editor. For instance, we added a ton of C# code fixes and refactorings such as rename and add missing using directives.

Add missing using directive in a Razor file

Other improvements include support for Find All References in closed Razor files, Go to Definition on Blazor component tag names, Razor formatting, better diagnostics, Razor intrinsic completions, and editing performance and stability for large projects and solutions. Give the new Razor editor a try and let us know what you think! To enable the new Razor editor, go to Tools > Options > Environment > Preview Features and select Enable experimental Razor editor, and then restart Visual Studio. You can share your feedback with us by creating Razor Tooling issues on GitHub in the ASP.NET Core repo.

Get involved

This was just a sneak peak 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.


Discussion is closed. Login to edit/delete existing comments.

  • hitesh davey 0

    These are good enhancements to improve developer productivity.

    Btw, What is the current status of this suggestion? For the last 3yrs, It is showing “under review”!!!

    “Procedure View” one of the most useful features of VB6 IDE which is still missing in VS.net IDE ever since ver 2002. I wise to see this feature so that developers can concentrate on one function/procedure when developing/debugging complex code. It is really distracting to see the entire source code when just one critical function/proc is being worked on. This feature will prove to be really productive to many developers if implemented.

    (For instance, Just imagine a case where you are editing a given page in a 50-pages word document without a page break; in such a case, you will end up viewing the entire document whereas your area of interest is only to edit a given page).

    Developers have asked for this feature on “UserVoice” but somehow voice is not begin heard by VS team. MS is keeping quiet on many valid user suggestions (and this is demotivating).

    • Mika DumontMicrosoft employee 0

      Hi Hitesh! Thank you for filing this feedback. I went ahead and moved this to our open source repository on GitHub for further discussion with the community which you can track here.

      • hitesh davey 0

        Mika, Thank you for your attention.

        I am still surprised why MS VS Team has not invested in “Task-focused Interface”.

        – “The primary goal of a task-focused interface is to scope the information shown in a computer application to just that relevant to the user’s current task”.
        – “Task-focused interfaces have been demonstrated to be effective in reducing information overload and improving programmer productivity”.
        Source: https://en.wikipedia.org/wiki/Task-focused_interface

    • Sergey Vlasov 0


      You can try my Task Canvas extension that lets you open a function or a code fragment in a separate window, and work with several code fragments side by side.

      • hitesh davey 0

        Vlasov, your Task Canvas extension tool is great; you have taken the idea of a task-focused interface to the next level! Will definatly try it out soon.

    • Igor Shigaev 0

      Check “Task Canvas” extension – seems what you need. You can wait for YEARS from MS or do yourself. :))

  • Oron Feinerman 0

    About “Remove unused references”. I was really looking forward to this feature, but in reality it is broken to the point of uselessness. These issues were reported in the developer community, but I find it ironic that such a broken feature gets so many mentions on DevBlogs.

    1. It does not show the actual name of the package – it removes the last part of it. For example, “Newtonsoft.Json” appears as just “Newtonsoft”. This makes it completely ambiguous when I have many packages with similar names (“Serilog.Sinks.Console”, “Serilog.Sinks.Debug”, etc. all appear as “Serilog.Sinks”). It seems to be intentional, but it makes absolutely no sense and can pretty much kill the usefulness of the feature.

    2. It sometimes suggests removing references that are definitely used explicitly. For example, it suggests removing every Project reference, regardless of whether it is used or not.

    3. For some projects, it crashes with “Object reference not set to an instance of an object.”

    • Mika DumontMicrosoft employee 0

      Hi Oron! Thanks for providing this feedback. In general we do not analyze runtime references and expect users to mark those as keep. We have an open issue which you can track here for 3. Do you mind filing an issue for 1 & 2 here so we can further investigate this?

  • Vincent D 0

    Question about “Remove unused references”.
    Does it only remove unused deps or also duplicated deps? Like if I have both a direct Newtonsoft.Json dependency and a transitive one through another package?

  • Paulo Pinto 0

    Lots of nice improvements, quite welcoming, provided we stick with C# and VB.

    Unfortunely F# keeps being that relative that no one wants at the party, while C++/CLI is that forgotten kid at the corner, .NET development tooling in plenty of Visual Studio workflows just isn’t for them.

  • Richard Deeming 0

    “in 16.10 Preview 2 we added an EditorConfig designer”

    Are you sure? I’m running 16.10.1, and there’s no designer for .editorconfig files.

    • Mika DumontMicrosoft employee 0

      Hi Richard! Do you have Mads Kristensen’s EditorConfig extension installed? If so we are working on fixing the following issue which you can track here.

  • Nhabep9x 0

    It’s great

  • Eugene Ivanoff 0

    1. “IntelliSense completion for preprocessor symbols” – Does not work for directives defined in code file (for instance, #define USE_RAZOR).
    2. “Remove extra blank lines” – Does not work. When used in explicit namespace, it has offers something like “Get overrides…” and “Get constructor Program()…” – and that’s all. For top-level statements the light-bulb does not show up at all.

  • Silva Singh 0

    It is looking amazing so far. But after reading the comments, thinking to use it and review it again here. It is going to be a real fun. Btw thanks

  • daniellittledev 0

    Most of these seem like C# productivity improvements, not .NET productivity improvements?

  • Rcmcpe ​ 0

    Seems almost all features mentioned in this article are copied from Resharper.

    • Gweltaz . 0

      You’ve never tried Steve Cadwallader’s CodeMaid, have you?
      I’m glad those features are now part of the standard VS experience, and am welcoming every upcoming ones!

      • Rcmcpe ​ 0

        Yes l am. l think Resharper is enough, especially for its inspections.

        Welcome, yes but with less expectance.They even can’t do a good copy. l tried Remove Unused References command, and it display many used nuget packages. Recent Microsoft softwares are full of flaws……

  • Igor Shigaev 0

    First of all, I recommend to avoid word “exciting” when you speak about ridiculous features like “remove unused refs”. IT IS NOT exciting. Just clean up a few LOC, which AFFECTS NOTHING.
    Second, “inheritance margin” is just rotating SAME FUNCTIONALITY available thru popup. You have nothing to do and you duplicate calls of same function??

    Intellisense from MS still in a status “stupidesense”. You cannot even insert full method call when call is obvious! Say, we have File.Close() function. If you write “f.” (and popup appears) and you select “Close”, STUPIDesense inserts just name(!!!). As a result you see “f.Close”, while help could be much better: “f.Close();” – why for 20 years you still cannot do simplistic help??

    That’s why people write extensions – they are tired of stupidity of your team – you do everything except really helpful things. Who is your manager? Why he has no IT education and why your plans always childish?? You have TONS of requests and you’re not able do distinguish REALLY HELPFUL. Your work so pathetic….

Feedback usabilla icon