Do you know these C# keywords, and how to use them like a pro?
This article is also available on Medium.
C# is like any other programming language: you first learn the basics and then, as you get better at it, you discover that there’s just an ocean left of features to uncover and try out! 🙂
I feel like that’s typically the case with C# numerous keywords that help optimise the structure of your codebase or define good data encapsulation, for example.
So, today, let’s talk about a few interesting C# keywords!
Trick #1: Data protection with
Something that is very important when you work on big projects, and especially when you start to collaborate with other devs, is to have your code reflect your team organisation. Oftentimes, this means deciding on conventions and good API design… but it can also be done via properly separating the different parts of your codebase and in particular encapsulating the data where needed.
Basically, the idea is to avoid having big globals variable that any part of the code can access and modify when possible, because those can quickly lead to uncontrollable and hard-to-track-down bugs.
Most C# developers know the basics of data encapsulation, where you try to pick the most restrictive accessor keyword between
public (very low restriction),
protected (restricted to the inheritance chain of the class) and
private (restricted to the class). But there’s another level of detail you can add with some additional keywords like
const is a shorthand for “constant” and it’s quite famous: as the name suggests, it allows us to say that a field or a variable has a constant pre-defined value that will never change.
However, this modifier imposes two important limitations on the initialised variable: it has to have a value that is evaluable at compile-time, and it can only have one (hardcoded) value.
This can be annoying if we want some fields in a class to get a different value depending on the constructor you’re using, for example, or if we want to give them a value that is evaluated at runtime.
To do this, we can use the
readonly keyword instead. This time, it lets us set the value of the class field either when it’s declared, or in the constructor of the class, while still preventing any further updates:
But keep in mind that the
readonly keyword only works for a field inside of a class! 🙂
sealed keyword doesn’t apply to fields and variables, but to classes – it’s a way of telling the compiler that this class cannot be inherited from (i.e. it can’t be the parent of another class).
Trick #2: The reverse – data “explosion” with
Even if data encapsulation and class hierarchy are important notions to keep your codebase clean and sound, there are still cases where do you don’t have the choice: you have to transform some part of your project in an external module, or you want to use a library by someone else that is alongside your code and needs to communicate with it.
Let’s discuss several techniques to deal with those kind of problems.
extern keyword is a method modifier that is essentially explicits the fact that some logic comes from elsewhere – namely a lib you import and call a function of. It’s typically used with the
DLLImport attribute to inter-operate with a service and calling unmanaged code:
(Example code from the Microsoft docs)
Another possibility is that you’re not using external dependencies, but you want to structure your codebase in a specific way and therefore can’t keep all your classes packed together as usual. In short, you’d like to define part of your class in a file, and then another part of the class in another file.
This can seem like a strange way to organise a project, but if you start to dive into big code and you want to easily dispatch tasks in your team, it can be nice to “split” your class in chunks but still keep it as one coherent object in the eyes of the compiler.
The trick here is to use the
partial keyword. It can be applied to classes, structs or interfaces, and lets you spread the definition of you logic over two or more files.
If you use this, you’ll have to re-wrap each of your logic chunks in the class declaration – and make sure to always have the exact same prototype, with the same access modifiers and all:
And for more advanced use cases, you have the
volatile keyword: this is a way of sharing a variable between multiple threads to allow several threaded processes to access or modify it. I won’t go into the details, but the official Microsoft docs linked before have various examples of it 😉
Trick #3: Iterating through data with
Sometimes, when you want to iterate through a series of C# items, you might define a list or an array containing them and then iterate through it. This is a good idea if you’ll need to re-use those items later on, and that you therefore want to store them for a while, but if it’s just for a one-time read, it can be a bit overkill.
In particular, it uses a lot of memory that then has to be freed once you’ve finished reading the container’s items – and with the C# garbage collection mechanism, this can lead to some slow downs. Even worse, you might be interested in just a subset, and actually want to discard the first items.
If you don’t plan on keeping the items and just want to iterate through them, a better solution can be to create an “on-the-fly” iterator thanks to the
yield keyword. This immediately tells the program that the method, operator or accessor the keyword is used in is an iterator (which means it has all that’s required to be used by a
foreach loop) without having to actually allocate memory.
Let’s first focus on
yield usage in methods.
The simplest case is to just return a bunch of numbers one after the other: each item in the iterator is created by a
yield return statement.
Of course, you can wrap the logic in a loop… or multiple ones!
If you want to interrupt your iterator early, you can use a
You can even go asynchronous and create some async/await couple for your iterator and your
foreach loop! (note the time stamps on the left for each output line) 🙂
Of course, the
yield keyword works very similarly for operators or getters; for example, here is a
get accessor that is “transformed” into an iterator by the
yield returns inside:
Trick #4: The power(s) of
If you’re familiar with C#, chances are that you’ve already seen the
default keyword be used in a
switch statement, like this:
More specifically, the
default keyword can also be interesting when you work with C# generics, at two steps of the process:
- either when you define a generic method in a derived class and want to override a specific base implementation from the parent class (more details on that over here)
- or when you’re inside a generic method or class and you want to get a new instance of your type with a default value
This last case is something that can happen quite a lot, and that might seem like a pain at first sight. Suppose you want to print the default value of a given type without knowing beforehand which type will be passed in – which is why you made a generic method.
A naive approach could be to just try and write down all cases manually:
But this is obviously quite risky and error prone. Chances are I’ll forget one, or mistype something, and get incomplete or wrong results.
Rather, I’d like to have some automated way of “guessing” the right default value, based on the type. Luckily, C# has us covered! You can use a default value expression to automatically get the right value based on your generic type (for example: 0 for a number,
false for a boolean,
null for a list or a string, etc.):
This way, you’re sure you’re not missing any case, and you’ll get a logical return value from your function! 🙂
Today, I showed a few util C# keywords and how they can help structure your projects, create data iterators or work with default values.
I hope you liked this short tutorial — and feel free to tell me in the comments what other C# topics you’d like to see me write about 🙂