
- •Table of Contents
- •About the Author
- •About the Technical Reviewer
- •Acknowledgments
- •Introduction
- •Installing Visual Studio
- •Visual Studio 2022 System Requirements
- •Operating Systems
- •Hardware
- •Supported Languages
- •Additional Notes
- •Visual Studio Is 64-Bit
- •Full .NET 6.0 Support
- •Using Workloads
- •The Solution Explorer
- •Toolbox
- •The Code Editor
- •New Razor Editor
- •What’s Available?
- •Hot Reload
- •Navigating Code
- •Navigate Forward and Backward Commands
- •Navigation Bar
- •Find All References
- •Find Files Faster
- •Reference Highlighting
- •Peek Definition
- •Subword Navigation
- •Features and Productivity Tips
- •Track Active Item in Solution Explorer
- •Hidden Editor Context Menu
- •Open in File Explorer
- •Finding Keyboard Shortcut Mappings
- •Clipboard History
- •Go To Window
- •Navigate to Last Edit Location
- •Multi-caret Editing
- •Sync Namespaces to Match Your Folder Structure
- •Paste JSON As Classes
- •Enable Code Cleanup on Save
- •Add Missing Using on Paste
- •Features in Visual Studio 2022
- •Visual Studio Search
- •Solution Filters
- •Visual Studio IntelliCode
- •Whole Line Completions
- •Visual Studio Live Share
- •Summary
- •Visual Studio Project Types
- •Various Project Templates
- •Console Applications
- •Windows Forms Application
- •Windows Service
- •Web Applications
- •Class Library
- •MAUI
- •Creating a MAUI Application
- •Pairing to Mac for iOS Development
- •Consuming REST Services in MAUI
- •The Complete Weather App
- •The Target Platforms
- •The Required NuGet Package
- •The Weather Models
- •The WeatherService
- •The MainViewModel
- •Registering Dependencies
- •Building the MainPage View
- •Using SQLite in a MAUI Application
- •The ToDoItem Model
- •The ToDoService
- •The MainViewModel
- •Registering Dependencies
- •Building the MainPage View
- •Managing NuGet Packages
- •Using NuGet in Visual Studio
- •Hosting Your Own NuGet Feeds
- •Managing nmp Packages
- •Creating Project Templates
- •Creating and Using Code Snippets
- •Creating Code Snippets
- •Using Bookmarks and Code Shortcuts
- •Bookmarks
- •Code Shortcuts
- •Adding Custom Tokens
- •The Server Explorer
- •Running SQL Queries
- •Visual Studio Windows
- •C# Interactive
- •Code Metrics Results
- •Maintainability Index
- •Cyclomatic Complexity
- •Class Coupling
- •Send Feedback
- •Personalizing Visual Studio
- •Adjust Line Spacing
- •Document Management Customizations
- •The Document Close Button
- •Modify the Dirty Indicator
- •Show Invisible Tabs in Italics in the Tab Drop-Down
- •Colorize Document Tabs
- •Tab Placement
- •Visual Studio Themes
- •Summary
- •Setting a Breakpoint
- •Step into Specific
- •Run to Click
- •Run to Cursor
- •Force Run to Cursor
- •Conditional Breakpoints and Actions
- •Temporary Breakpoints
- •Dependent Breakpoints
- •Dragging Breakpoints
- •Manage Breakpoints with Labels
- •Exporting Breakpoints
- •Using DataTips
- •Visualizing Complex Data Types
- •Bonus Tip
- •Using the Watch Window
- •The DebuggerDisplay Attribute
- •Evaluate Functions Without Side Effects
- •Format Specifiers
- •dynamic
- •hidden
- •results
- •Diagnostic Tools
- •CPU Usage
- •Memory Usage
- •The Events View
- •The Right Tool for the Right Project Type
- •Immediate Window
- •Attaching to a Running Process
- •Attach to a Remote Process
- •Remote Debugger Port Assignments
- •Remote Debugging
- •System Requirements
- •Download and Install Remote Tools
- •Running Remote Tools
- •Start Remote Debugging
- •Summary
- •Creating and Running Unit Tests
- •Create and Run a Test Playlist
- •Testing Timeouts
- •Using Live Unit Tests
- •Using IntelliTest to Generate Unit Tests
- •Focus IntelliTest Code Exploration
- •How to Measure Code Coverage in Visual Studio
- •Summary
- •Create a GitHub Account
- •Create and Clone a Repository
- •Create a Branch from Your Code
- •Creating and Handling Pull Requests
- •Multi-repo Support
- •Compare Branches
- •Check Out Commit
- •Line Staging
- •Summary
- •Index

Chapter 3 Debugging Your Code
Listing 3-8. Modified Subject Class
[DebuggerDisplay("Code: {SubjectCode, nq}, Subject: {SubjectDescription, nq}")]
public class Subject
{
public int SubjectCode { get; set; }
public string SubjectDescription { get; set; }
}
Start debugging your code again and have a look at your Watch window after adding the DebuggerDisplay attribute. Your item values are more readable as seen in Figure 3-31.
Figure 3-31. The lstSubjects variable values with DebuggerDisplay
The use of “nq” in the DebuggerDisplay attribute will remove the quotes when the final value is displayed. The “nq” means “no quotes.”
Evaluate Functions Without Side Effects
While debugging an application, we probably do not want the state of the application to change because of an expression we are evaluating. It is, unfortunately, a fact that evaluating some expressions might cause side effects.
To illustrate this, we will need to write some more code. We will be creating a class called Student that contains a List of Subject as seen in Listing 3-9.
188

Chapter 3 Debugging Your Code
Listing 3-9. The Student Class
public class Student
{
private List<Subject> _subjectList; public Student() { }
public Student(List<Subject> subjects) => _subjectList = subjects; public bool HasSubjects() => _subjectList != null;
public List<Subject> StudentSubjects
{
get
{
if (_subjectList == null)
{
_subjectList = new List<Subject>();
}
return _subjectList;
}
}
}
In this class, we have a HasSubjects() method that simply returns a Boolean indicating if the Student class contains a list of subjects. We also have a property called StudentSubjects that returns the list of subjects. If the list of subjects is null, it creates a new instance of List<Subject>.
It is here that the side effect is caused. If the HasSubjects() method returns false, calling the StudentSubjects property will change the value of HasSubjects().
This is better illustrated in the following screenshots. Create a new instance of Student and place a breakpoint right after that line of code (Figure 3-32).
Figure 3-32. Place a breakpoint after Student
189

Chapter 3 Debugging Your Code
If we now use the Watch window to look at the value returned by the HasSubjects() method, we will see that it returns false (Figure 3-33).
Figure 3-33. HasSubjects() method returns false
When we call the StudentSubjects property, we see this side effect come into play in Figure 3-34. As soon as this property is called, the value of the HasSubjects() method changes.
This means that the state of our Student class has changed because of an expression that we ran in the Watch window.
This can cause all sorts of issues further down the debugging path, and sometimes the change might be so subtle that you don’t even notice it. You could end up chasing “bugs” that never really were bugs to begin with.
Figure 3-34. HasSubjects() method value has changed
190