Search icon
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletters
Free Learning
Arrow right icon
Refactoring with C#

You're reading from  Refactoring with C#

Product type Book
Published in Nov 2023
Publisher Packt
ISBN-13 9781835089989
Pages 434 pages
Edition 1st Edition
Languages
Author (1):
Matt Eland Matt Eland
Profile icon Matt Eland

Table of Contents (24) Chapters

Preface Part 1: Refactoring with C# in Visual Studio
Chapter 1: Technical Debt, Code Smells, and Refactoring Chapter 2: Introduction to Refactoring Chapter 3: Refactoring Code Flow and Iteration Chapter 4: Refactoring at the Method Level Chapter 5: Object-Oriented Refactoring Part 2: Refactoring Safely
Chapter 6: Unit Testing Chapter 7: Test-Driven Development Chapter 8: Avoiding Code Anti-Patterns with SOLID Chapter 9: Advanced Unit Testing Chapter 10: Defensive Coding Techniques Part 3: Advanced Refactoring with AI and Code Analysis
Chapter 11: AI-Assisted Refactoring with GitHub Copilot Chapter 12: Code Analysis in Visual Studio Chapter 13: Creating a Roslyn Analyzer Chapter 14: Refactoring Code with Roslyn Analyzers Part 4: Refactoring in the Enterprise
Chapter 15: Communicating Technical Debt Chapter 16: Adopting Code Standards Chapter 17: Agile Refactoring Index Other Books You May Enjoy

Defensive Coding Techniques

Code is almost organic and evolves over its lifetime as new features are added, fixes are implemented, and refactorings occur at regular intervals. As code changes and developers enter and leave the project, there’s a chance that some of these changes may introduce bugs.

In Part 2 of this book, we discussed testing strategies for detecting these bugs before they reach production. In this chapter, we’ll talk about a few additional techniques that help developers catch and resolve bugs during development. Along the way, we’ll also explore a few newer features in C# and their roles in keeping your code stable and healthy.

We’ll cover the following topics in this chapter:

  • Validating inputs
  • Protecting against null
  • Moving beyond classes
  • Advanced type usage

Technical requirements

The starting code for this chapter is available from GitHub at https://github.com/PacktPublishing/Refactoring-with-CSharp in the Chapter10/Ch10BeginningCode folder.

The code in this chapter talks to a REST API, which will require an active internet connection.

Introducing the Cloudy Skies API

Our fictitious sample organization, Cloudy Skies, has a pre-existing set of web services in the form of a public REST API. This API intends to allow interested organizations to pull information about Cloudy Skies flights through the API. However, a steady amount of support tickets has proven that organizations are having a hard time adopting the API and using it in approved ways.

In response, Cloudy Skies has built a .NET library to help others more easily use the API.

Early testing of this library is promising, but some developers are still encountering confusing errors that ultimately appear to be related to the data they’re passing the library.

The development team decided that validating parameters to public methods would help improve the adoption of their library by finding issues sooner. We’ll explore this change in the next section.

Validating inputs

Input validation is the act of verifying that any inputs to your code, such as parameters or current property values, are correct before performing the requested work. We validate inputs to public methods to detect potential issues early on.

To illustrate the importance of this, let’s look at a method that doesn’t validate its inputs:

public FlightInfo? GetFlight(string id, string apiKey) {
  RestRequest request = new($"/flights/{id.ToLower()}");
  request.AddHeader("x-api-key", apiKey);
  LogApiCall(request.Resource);
  return _client.Get<FlightInfo?>(request);
}

The GetFlight method takes in an id parameter indicating a flight number, such as “CSA1234,” whereas the apiKey parameter represents a token that must be supplied to interact with the API and get a response. Think of the token as something like a digital keycard that Cloudy Skies issues to interested organizations...

Protecting against null

British computer scientist, Tony Hoare, is generally credited as the inventor of the null reference in programming. In 2008, he famously apologized for it, calling it his “billion-dollar mistake.” This was due to the countless bugs and crashes that have occurred in various programming languages when code attempted to interact with variables currently holding null values. While I can’t fault Tony Hoare, nulls can certainly be dangerous.

In .NET, this comes in the form of a NullReferenceException error, as we saw earlier in this chapter. You get a NullReferenceException error any time you attempt to invoke a method or evaluate a property on a variable that currently holds a null value.

Before C# 8, developers needed to be explicitly aware that any reference type could hold a null value and write conditional logic, such as the following code:

if (flight != null) {
 Console.WriteLine($"Flight {flight.Id}: {flight.Status}"...

Moving beyond classes

In C# 9 and beyond, Microsoft has made concerted efforts to give developers new options for working with classes through things such as record types, init-only properties, primary constructors, and more.

In this section, we’ll explore how these newer C# constructs can improve the design of your classes.

Preferring immutable classes

In recent years, immutable classes have become more and more popular. This immutability refers to the inability to change an object after it has been created.

What this means is that once an object exists, you cannot modify its state and instead are limited to creating new objects that are like the original. If you’re familiar with working with string and DateTime objects in .NET, you’ve seen this concept with methods such as ToLower on string and AddDays on DateTime returning a new object instead of modifying the original object.

Let’s look at a small class representing a boarding pass that...

Advanced type usage

In this final section of this chapter, we’ll see how new and old language features help you build better types.

Exploring pattern matching

It turns out that we can use the same style of syntax we used with expressions earlier to conditionally match different objects through pattern matching.

To explain what I mean, let’s start with an example that loops over different boarding passes:

List<BoardingPass> passes = PassGenerator.Generate();
foreach (BoardingPass pass in passes) {
  if (pass is { Group: 1 or 2 or 3,
                Flight.Status: FlightStatus.Pending
              }) {
    Console.WriteLine($"{pass.Passenger} board now");
  } else if (pass is { Flight.Status: FlightStatus.Active
       ...

Summary

In this chapter, we looked at a variety of ways of ensuring your classes are safe and reusable through means such as argument validation, caller member information, nullability analysis, and using modern C# features such as record classes, primary constructors, pattern matching, and enhanced properties with the required and init keywords.

These language features help you detect issues earlier in development, work with objects more effectively, and write fewer lines of code overall.

This concludes Part 2 of this book. In Part 3, we’ll look at how AI and code analysis tools can help you and your team sustainably build better software.

Questions

Answers the following questions to test your knowledge of this chapter:

  1. How can throwing exceptions be beneficial to your code?
  2. What are the various ways you can declare a property in C#?
  3. What are the various ways you can instantiate an object in C#?
  4. What are the differences between classes and record classes?

Further reading

You can find more information about features discussed in this chapter at these URLs:

lock icon The rest of the chapter is locked
You have been reading a chapter from
Refactoring with C#
Published in: Nov 2023 Publisher: Packt ISBN-13: 9781835089989
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime}