Yesterday, I was fortunate enough to be invited to speak at Visug, the .NET User Group in Belgium. Attendance was good (about 35-40 people) though it could have been better should the road access hadn't been impacted by massive traffic delays. Nonetheless, the show must go on and we did the talk as planned. For those that missed the talk, I've recorded the whole (I think I did since the camera battery died at some point) session and I will be posting a link to it shortly.
A lot of people asked me whether they could get access to the slides. You can get the [slides here](http://www.slideshare.net/christosmatskas/visual-studio-2015-productivity-tips-tricks" target="_blank). However, since this was a really demo-heavy session, I decided to attach my notes as well. The notes are a crude form of transcript and I used them to drive my session. Using the notes, slides and video, you should be able to revisit all the cool features I showed in my Visual Studio 2015 demo.
The talk can be broken down into 3 distinct parts@
- General IDE improvements
- Roslyn & C# 6
- Debugging in VS2015
If you can't be bothered with reading along, jump straight to the video and enjoy 1.5hrs of VS2015 goodness:
General IDE Improvements
- Menu Bar (Upper and lower case). Tools -> Options -> Environment -> General -> Apply title casing to menu bar
- Roaming settings (theme & casing, environment, fonts, keyboard shortcuts, Tabs and Windows, Startup, text editor). Tools -> Options -> Environment -> Synchronised settings. Roaming can be disabled per device.
- Notifications - Flag icon at top right hand corner. Each notification can be dismissed and wont show up until next minor version update.
- Multiple drag and drop of tabs to new window. Hold Ctrl down and click on multiple tabs. Drag them out to a new space outside the main Visual Studio window.
- Solution explorer can be replicated across multiple windows. In Solution Explorer, right click on top-level solution and choose -> New solution explorer view from the context menu
- Dock and un-dock. All windows can be docked and un-docked (float). To restore any undocked window to its original location, press Ctrl + double click. This works on any docked window
- Pin tabs using the pin button on each tab. Pinning ensure that the tabs that matter the most stay in the front. All other opened tabs will open right after the pinned tabs. You can also re-order pinned tabs.
- Preview tab (opens documents on right-most corner of tab well). This feature keeps you tab well clean and helps during debugging. Promote by adding code or using the mouse to press on the Keep Open button on the tab.
- Tab Split View. At the top of the scrollbar, drag the splitter to the middle of the screen in order to have a split view of the same file. Changes to either part will be automatically reflected on both parts.
- Split view (horizontal and vertical): Right click on tab -> New horizontal/vertical tab group
- Go to containing folder. Right click on any folder in Solution Explorer and choose -> Open folder in file explorer
- Navigate To: Ctrl+, for in-line document navigation
Quick Launch and Search
- Quick launch (Qtrl+Q) is a gift that keeps on giving. You can use it to search anything you need to find in the options or in the menu.
- Quick Filter/Scope your search results by using the @ symbol. You have 5 options to scope the search: most recent, menu, options, open documents, nuget packages
-In general, Quick Launch is a great tool to learn shortcuts as well. The more you use it, the more you'll realize how powerful it is. On the downside, you may forget where all your windows and options are. But I don't see this as an issue :)
Almost all windows come with search. Search is a lot more integrated within the IDE, it's more powerful and a lot less invasive. The invesive part is particularly important because the focus is now on enabling you to achieve your tasks without blocking your workflow with modal windows.
- Tools -> Options -> Ctrl+E to highlight and use search
- In the Output Window -> Ctrl+F to bring up search. You'll notice that it's the same search that you get in the code editor.
- In the Error List windows the search is built in and as advanced as you would expect it to be. The error list also includes links to the error definition so you can quickly figure out what's wrong.
- In solution explorer, the search bar allows you to search for files, projects, and items within files
- In the solution explorer search bar, press Alt+Arrow down to tweak the search options. The "Search Within External Items" option is for searching in the external dependencies folder but this is only applicable to C++ projects.
- From anywhere in the IDE, press Ctrl+# to focus on the search bar in Team explorer
The Power of Roslyn
- Roslyn is the new, improved, open-source .NET compiler, written from the ground up exclusively in C#
- It looks exactly the same as the editor you're used to, but offers a much better experience. A lot of modal windows have been replaced with less invasive UI analogies.
- Extra highlighting. Collapse/expand code sections (hover over ellipsis to view full code) to experience a much richer popup with code highlighting
- Light bulb - the bulb appears when the analyser has smart refactoring options and suggestions about your code
- When the light bulb is not available, smart refactoring can be invoked with Ctrl+.
- Inline renaming can also be invoked with Ctrl+R,Ctrl+R while the cursor lies on a specific element
- Roslyn can take further advantage of plug & play analysers that provide real-time code analysis and compilation. Additional analysers can be downloaded from NuGet
- NuGet is non-modal and has an improved UI. NuGet 3.2 is out today!
C# 6
To showcase some of the new C# 6 features we will create a new Console application in Visual Studio. New -> New Console project. Right click on the project in Solution Explorer and then set the language options Properties -> Build -> Advanced -> Language version -> C#6
- static using. Using this feature means that you can do away with fully qualified namespace resolution. Instead of
Console.WriteLine()
you can simply do this
using static System.Console;
...
WriteLine("blah");
- Auto property initializer. The names says it all, but in case you're unsure, you can initialize properties with default values, without the need for a constructor, like this
public class Student
{
public int StudentId { get; set; }
public string Name { get; set; } = "Mike Tyson";
public int Age { get; set; }
}
- Dictionary Initializers. There's a new way for initializing dictionaries:
static Dictionary<string, string> GetTeachers()
{
// old way
var teacherDictionary = new Dictionary<string, string>
{
{"John Smith", "Maths" },
{"Jade Smith", "History" },
{"Paul McCartney", "Physics" }
};
// new way
var teacherDictionary2 = new Dictionary<string, string>
{
["John Smith"] = "Maths",
["Jade Smith"] = "History" ,
["Paul McCartney"] = "Physics"
};
return teacherDictionary;
}
- Exception Filters: No more unwinding of the stack!
public static void TestException()
{
try
{
throw new Exception("Error");
}
catch (Exception ex) when (ex.Message == "ReallyBadError")
{
// this one will not execute.
}
catch (Exception ex) when (ex.Message == "Error")
{
// this one will execute
WriteLine("This one will execute");
}
}
- Async/Await in try/catch/finally
public static async void TestExceptionAsync()
{
try
{
throw new Exception("Error");
}
catch
{
await Task.Delay(2000);
WriteLine("Waiting 2 seconds");
}
finally
{
await Task.Delay(2000);
WriteLine("Waiting 2 seconds");
}
}
- nameof. This function can be used instead of magic strings when needing to reference variable names in strings
public static void TestNameOf(string name)
{
WriteLine(name);
if(string.IsNullOrEmpty(name))
{
WriteLine($"Empty parameter provided: {nameof(name)}");
}
}
- String Interpolation. This feature allows you to use any variable within a string composition without needing to use "concatenation" or
string.Format()
. You'll notice that we also get full IntelliSense.
static void Main(string[] args)
{
var student = new Student { StudentId = 1, Age = 3 };
WriteLine($"The student name is: {student.Name}");
}
}
- Null Conditional Operator. The operator checks to see if a referenced property is initialised (not-null) and then returns the value. If the property under evaluation is not initialised, it will return null.
var someValue = person?.Name;
Another cool feature with the Null Conditional Operator is that you can daisy chain calls like so:
string[] names = person?.Name?.Split(' ')
In this case, Split()
will only be invoked if both person
and person.Name
are not null :)
Blown away yet? Let's curry on...
WPF editor
-
The WPF editor has seen a real transformation and has been improved all around. A lot of work has gone into rebuilding the editor from the ground up in order to provide an enhance development experience.
-
Peek Into. From within the XAML editor, you can peek into any C# code, such as model binding properties, event handlers etc
-
Live Visual Tree (in Debug mode). Allows you to use a selector to choose any item from the current running window and drill down to the visual tree. This will be very familiar to anyone that has worked with the browser dev tools against any HTML page.
-
Live Property Explorer (in Debug mode). This is the other half of the Live Visual Tree and allows you to edit properties on the XAML page at run time in order to fix visual problems.
Debugging
- Start a debugging session using the Step Into/Over buttons. It will take you to the application entry point as long as you have Only My Code enabled.
- View executed method return values from line above using the Autos or Locals windows.
- View executed method return values (for non-void methods) using the pseudo variable $ReturnValue<1,2,3> on the Watch or Immediate windows.
- Set Next Statement Debugger -> right click -> Set Next Statement or drag the yellow arrow key and drag it to the desired location
- On lines with multiple method calls, jump straight into a specific method with right click -> Step Into Specific. You can decide which method to step into using the popup window (available since VS2010)
- Right click -> Run to Cursor (sets a one-time breakpoint). You can also use this to kick off debugging session.
- While debugging use edit & continue to fix bad code. This is an in-memory fix and the code is "dirty" until you stop debugging and save the file.
- Step Out from a method to the previous method in the call stack (one up) using Shift+F11
- Step Out using the call stack window. Right click to method you want to step out select Run to cursor
From this point on, the video may not match the transcript since I was jumping around trying to fit as much as I could into the session. There's a lot to cover!
-
Debugger.IsAttached ->Debugger.break. This is like embedding breakpoints in code. If
Debugger.Break
is set without isAttached is set, then the application will crash because this feature throws a custom exception. Ensure you wrap it so that you don't experience this error when running in production. -
Visualizers (magnifying glass on tip points [hover over property]) can be used on any object in code while debugging. There is an option now to build custom visualizers and you can download custom visualizers from the Visual Studio gallery. By default, Visual Studio comes with 4 visualizers for strings: Text, XML, HTML, Json. The Json Visualizer allows searching as well. The HTML visualizer uses the built-in IE version you have installed on your machine so expect to see consistent behaviour and rendering.
-
For datasets, there is a built-in dataset visualizer. If the dataset contains multiple tables, there is a way to switch between datatables
-
For WPF, there is also a built-in WPF visualizer and you get a window with the tree view of the XAML. While on break, move to locals window and display the visualizer.
-
You can Ctrl+A,Ctrl+C to copy data from Text and XML Visualizers (Not available for WPF or Json)
-
Use the DebuggerDisplay annotation on a class to display importaqnt object values during debugging using tip points (hover over object).
[DebuggerDisplay("Id:{AppID}")]
-
PeekDefinition. Right click on any class or method -> peek definition. Also available as a keyboard shortcut -> Alt+F12. This is the same as using an overriden ToString() method.
-
On any popup, if you press Ctrl and it will become transparent
-
Pinning properties allows you to avoid using tip point. Pinning properties will make them stay in the context of the pinned window. Pins stay after you finish debugging and allows you review values after you finish execution. You can add notes as well. (Available since VS2010)
-
To keep monitoring a property outside the current scope, float the property pin and move window outside code (i.e on toolbar), right click on property and choose "Make ObjectID". Notice the dollar sign. Go to Watch -> type $1. This will make the pseudo-object to stay permanently in scope.
-
You can export and import data tips and breakpoints
-
When working with complex objects with hierarchy levels, you can add a watch at any level.
-
Conditional Breakpoints - Conditional Expression,
-
Hit Count (faster)
-
Filter is used for multithreaded debugging. In expressions, we get IntelliSense. It's not modal so that you can copy stuff from the code window.
-
Go to AppDataProvider -> GetAppsByType() -> set conditional breakpoint in line before return();
-
Performance remains as crappy as in previous versions but there's also active effort to improve this
-
You can edit any property value while debugging.
There's a lot of love for Lamda expressions.
- You can execute Lamda expressions on any debug window.
- You can add Lamda expressions on conditional breakpoints as long as you have no dependencies to native code
Diagnostis in Visual Studio have been added to work by default but if you cannot see them, you can enable them like this: Debug -> Options -> General -> Enable diagnostic tools while debugging
- By executing any method, you get time to execute as "n seconds elapsed".
in 2015. This features has totally eliminated the need No need to use StopWatches as an (inefficient and unreliable) way to measure performance.
I hope you found this useful and feel free to let me know of any other tips and tricks you may like to use frequently in the comments.