NDepend Blog

Improve your .NET code quality with NDepend

C#_Features_A_List_of_the_Best_Ones

C# Features: An Exhaustive List of the Best Ones

December 18, 2018 6 minutes read
The first post I wrote for the NDepend blog was about C# 8.0 features. That post inspired a sequel, followed by the series’ final chapter. Those posts dealt with the future. Today’s post, on the other hand, is all about what’s already here. I’ll make a list of the C# features I consider to be some of the best ones. For brevity’s sake, I’ll do the briefest overview of each feature, though.
Also, be warned: I’m going to use “C# feature” loosely throughout this post. So you’ll see some items that are, technically, .NET frameworks features. The reason for this choice is that, for many developers, C# and .NET are interchangeable. That’s the way they think, talk, and google about this topic.
Without further ado, let’s dive into it.

Type Inference

The first C# feature on our list is type inference. In a nutshell, type inference is the ability of the compiler to know the type of a given value without the need for the developer to explicitly declare it. Here are some examples:

As you can see from the examples above, type inference works not only when the right-hand side is a literal value. The compiler is also able to infer the type based on the return type of a method or property.

Anonymous Types

Anonymous types are a convenient way to encapsulate a set of properties into an object without having to explicitly declare a class beforehand. Let’s see a quick example:

In the code above, we declare a new anonymous type, which will contain the Name and Age properties, respectively. And we immediately assign it to the person variable.

Can you see how vital type inference is to this feature? The compiler must infer the types of the properties themselves but also the type of the newly created anonymous object as well. This feature would’ve been impossible without type inference.

Properties as a Language Construct

One of the fundamental concepts in OOP is encapsulation. A consumer should not concern itself with the implementation details of the object it’s accessing. Instead of exposing public fields directly, we should use methods for setting the values of our fields—and also retrieving them. These are called, not surprisingly, getters and setters, or even mutator methods. Writing a lot of those gets old fast, though. C# allows you to avoid that by offering the same pattern as a language construct: properties.

The class would then be used like this:

Automatic Properties

A typical usage pattern of properties in C# is to only assign to or read from a private field, without performing any additional logic. People do this a lot, especially when coding DTOs (data transfer objects). The C# language not only recognizes this pattern but also makes it a first-class citizen! So instead of writing code like this:

You could simplify it to this:

The compiler then generates a private backing field for your class automatically! Pretty neat, huh?

Conditional Operator (?)

This C# feature is pretty common in other languages: the conditional operator, sometimes also called the ternary conditional operator. You can think of it as a shorter version of an if statement that returns a value. With it, you can write code that assigns a value based on a condition—same as you would with an if statement, but more shortly.

Here’s an example using an if statement:

And now the same example, but this time using the conditional operator:

Null Coalesce Operator (??)

Here’s a familiar pattern developers use when dealing with nulls: to check a variable for null before assigning and to use a default value if it turns out to be null. It looks something like this, in practice:

In the code above, we verify if the Books parameter is null. If that’s the case, we instantiate a new list and assign it to the Books property, to avoid a nasty NullReferenceException. Pretty standard stuff, right?

It’d be possible for us to simplify the code above a little bit using the ternary conditional operator, which you already know. But since you already know that one, I’ll cut to the chase and show you the C# feature that can simplify the code even further: the null coalesce operator. Check it out:

In the code above, we use the ?? operator, a.k.a. the null coalesce, operator, to check the Books parameter. If it’s not null, its value is assigned to the Books property. Otherwise, the value in the right-hand side (in our case, a new list of Book instances) gets assigned to the property instead.

Throw Expression

Here’s another common pattern that you’ve likely done as a C# developer that involves nulls: checking a parameter and throwing an exception if it turns out it’s null. You’d usually do it like this:

Sure, it’s not the worst code ever written, but it’d be nice if we could simplify it somehow. Well, another C# feature to the rescue! What follows is the simplified version of the code, using throw expressions along with the null coalesce operator:

From 11 lines down to five. Not that bad, right?

Nameof

You might’ve noticed that the code in the second example still has room for trouble, despite being shorter and simpler than the previous version. Why? Simple: we’re hardcoding the parameter name when throwing. If the names of the parameters ever change (spoiler alert: everything changes in software) and we forget to alter the string we’ve hardcoded, the clients of our code might become confused reading stack traces in the future.

But don’t worry: there’s a C# feature for that. And it’s called nameof. As its name suggests, it obtains the name of a variable, type, or member. Take a look at some examples:

The code from the previous example, with the use of the nameof feature, would look like this:

Null-Conditional Operator (?.)

The next C# feature on our list also has to do with nullability, and it’s called the null-conditional operator. Consider the code below:

Let’s assume commit will never be null. But if you know your Git, you’ll know that not all commits have parents. So Parent could be null. Before we go and check that, think about the amount of code we’d have to write to check, say, five properties. And of course, Author could be null as well.

So, the C# feature known as the null-conditional operator can help us out here. It checks a member for null and only allows the access to happen if it’s not null. Otherwise, the whole expression is evaluated as null. It might sound a bit complicated, but it’s not. Here are some quick examples:

Did you notice how in the last example we used the feature along with the null coalesce operator to quickly assign a default value? Interesting, right? We could apply the same technique to the GetInfoAboutCommitParent example:

I really like the way some C# features compound together to allow developers to write clean and concise code like that.

Now It’s Back To You

In today’s post, we’ve covered some of the best features the C# language has to offer. Of course, the list is highly subjective, so we’d like to hear your opinion as well. Did your favorite C# feature make it to the list? Would you have suggestions? Leave your opinion in the comments box below and let’s take it from there.