Sponsored
• Join Postman CTO, Ankit Sobti, and Head of Customer Experience and Success, Kristine Chin, at this webinar which delivers the information you need to maximize the success of your API products, reduce friction to collaboration, and to provide a world-class experience for your developers, partners, and customers. Join here.
Many thanks to the sponsors who make it possible for this newsletter to be free for readers. Become a sponsor.
Guard clauses in .NET are a programming practice used for improving the readability and reliability of code. They are simple checks at the beginning of a function or a method that validate inputs or conditions before proceeding with the rest of the code. Guard clauses in .NET effectively address several common programming problems: they reduce complexity and increase readability by preventing deeply nested code structures; enhance code safety and reliability by validating inputs or conditions at the outset, thus averting potential runtime errors or unexpected behavior; and they clarify the code's intent by explicitly stating the preconditions needed for subsequent code to execute correctly. This not only makes the code easier to understand but also simplifies maintenance and future modifications, as the requirements and constraints are clearly laid out at the beginning of the method or function. How to implement it? Let's take a look deeply!
Under normal circumstances, this would be a common piece of code you would see in an application.
public class Person{ public string Name { get; private set; } public Person(string name) { if (string.IsNullOrEmpty(name)) { throw new ArgumentException("Name cannot be null or whitespace.", nameof(name)); } Name = name; }}
There is nothing unknown here. We check if the name is filled in and throw an exception if it is not. Note: I am not a supporter of this practice that exceptions are thrown in situations when it is not necessary. In this case, I would use the Result object with the Failure status. Certainly, this issue is about another problem that we are solving, so we will stick to exceptions. What's wrong here? Nothing specific. But code readability is not something. Just imagine, let's now insert another check for us (is it in the right format, good length, etc...). The function will have 20 lines of code just for checking. Let's make it sexier... :)
We will create a static class Ensure. I like to call it that, so that one can immediately conclude what it is about. Within it, we will add the first method that the class will check. This code will actually read in English:.
public static class Ensure{ public static void NotNullOrEmpty(string? value, string? paramName = null) { if(string.IsNullOrEmpty(value)) { throw new ArgumentException("The value can't be null", paramName); } }}
If this is the case, the job and responsibility of throwing the exception is taken over by the Guard Clause class. In this way, we have a clean and legibly written method. We can see that below:
public Person(string name){ Ensure.NotNullOrEmpty(name); // Logic}
Instead of constantly passing the name of the parameter for which an exception is thrown, which was passed as paranName in the NotNullOrEmpty() function, you can use the attribute CallerArgumentExpression("value") , where value represents the attribute for which we need a name. What will happen? At runtime, this value will be read and assigned to the paramName attribute. This can be very useful in many situations, and we avoid hardcoding the parameter names and the potential error of writing the wrong parameter. Take a look here:
public static class Ensure{ public static void NotNullOrEmpty(string? value, [CallerArgumentExpression("value")] string? paramName = null) { if(string.IsNullOrEmpty(value)) { throw new ArgumentException("The value can't be null", paramName); } }}
Today I did not invent electricity like Nikola Tesla. Many developers have already created quality libraries for the same purpose. You can see some of them on the following links: • Ardalis • Dawn • Throw Whichever you choose, you won't have any problems. And if you want more control, you can always create your own custom, as I showed.
In today's issue, I showed you how to improve readability and shift the responsibility of throwing exceptions (if necessary) to another class that should handle it. And in this way, you will increase the readability of your method that deals with logic. By using Guard Clauses. I showed you how to create your own Custom Guard Clause. I explained what the CallerArgumentExpression attribute is and how to use it. And finally, if you wouldn't do it, I gave you an example of 3 existing libraries that do it in an excellent way. That's all from me today.
Want to enforce clean code automatically? My Pragmatic .NET Code Rules course shows you how to set up analyzers, CI quality gates, and architecture tests - a production-ready system that keeps your codebase clean without manual reviews. Or grab the free Starter Kit to try it out.
Stop arguing about code style. In this course you get a production-proven setup with analyzers, CI quality gates, and architecture tests — the exact system I use in real projects. Join here.
Not sure yet? Grab the free Starter Kit — a drop-in setup with the essentials from Module 01.
Design Patterns that Deliver — Solve real problems with 5 battle-tested patterns (Builder, Decorator, Strategy, Adapter, Mediator) using practical, real-world examples. Trusted by 650+ developers.
Just getting started? Design Patterns Simplified covers 10 essential patterns in a beginner-friendly, 30-page guide for just $9.95.
Every Monday morning, I share 1 actionable tip on C#, .NET & Architecture that you can use right away. Join here.
Join 20,000+ subscribers who mass-improve their .NET skills with actionable tips on C#, Software Architecture & Best Practices.
Subscribe to the TheCodeMan.net and be among the 20,000+ subscribers gaining practical tips and resources to enhance your .NET expertise.