In this week's newsletter I want to highlight a few interesting things that are now available with the release of C# 11 and .NET 7.
In case you missed it, .NET 7 was released November 8th.
There are many new features, and you can be sure I had a hard time choosing which ones to highlight.
Here's what we are going to cover:
- Required members
- Generic attributes
- Static abstract members in interfaces
-
file
keyword - LINQ Order and OrderDescending
Let's see what the new features look like.
Required Members
We can now define a class member as required by using the required
keyword. It can be applied to a field or property and it tells the compiler these members must be initialized by all constructors or by the object initializer.
Why is this useful?
Before C# 11 , the only way to enforce a property being set was through a constructor. If you used an object initializer you could bypass the constructor and not initialize some properties.
Here's how you can say that a property is required:
public class ContentCreator
{
public required string Firstname { get; init; }
public string? MiddleName { get; init; }
public required string LastName { get; init; }
}
If you try to create a new ContentCreator
instance without initializing the required
properties you get a compile error:
var creator = new ContentCreator
{
FirstName = "Milan" // Error: No LastName
}
Generic Attributes
You can now declare a generic class whose base class is Attribute
.
Before C# 11 , if you wanted to pass in a type as a parameter to an Attribute
you would need to pass it through the constructor:
public class TypedAttribute : Attribute
{
public TypedAttribute(Type t) => Param = t;
public Type Param { get; }
}
And here's how you would use it with the typeof
operator:
[TypedAttribute(typeof(int))]
public int Method() => default;
Using the generic attributes feature, you can now define it like this:
public class TypedAttribute<T> : Attribute { ... }
Now, we can specify the type parameter as a generic argument:
[TypedAttribute<int>()]
public int Method() => default;
Static Abstract Members in Interfaces
This is a very interesting feature that allows abstracting of static operations. An example of this would be operators.
public interface IMonoid<TSelf> where TSelf : IMonoid<TSelf>
{
public static abstract TSelf operator +(TSelf a, TSelf b);
public static abstract TSelf Zero { get; }
}
How can we use the IMonoid
interface?
It may be confusing at first, since the members are virtual and there is no instance to call the virtual members on. The solution is to use generics and let the compiler infer the rest.
Here's a simple example:
T AddAll<T>(params T[] elements) where T : IMonoid<T>
{
T result = T.Zero;
foreach (var element in elements)
{
result += element;
}
return result;
}
If you want to learn more, check out the docs onstatic abstract interface methodsand generic math.
File Keyword
With the new file
keyword you can define a type whose scope and visibility is restricted to the file in which it is declared.
file class HiddenClass
{
}
This feature is practical when used inside of source generators, to avoid collisions when naming generated types.
But you may be able to find a use for it in your application.
LINQ Order and OrderDescending
The new Order
and OrderDescending
methods allow us to sort anIEnumerable
, which simplifies the code for sorting.
Here's an example of ordering an array:
var array = new[] { 19, 91, 21 };
var arrayAsc = array.Order();
var arrayDesc = array.OrderDescending();
I want to highlight that IQueryable
also supports the new methods.
Will You Upgrade to .NET 7?
.NET 7 is not an LTS (Long Term Support) release, and will be in support until May 2024, with .NET 8 releasing in November 2023.
Here are a few reasons why you should consider upgrading:
- Major performance improvements
- New features in .NET 7
- New features in EF Core 7
- Easier migration to .NET 8
I will be moving some of my new projects from .NET 6 to .NET 7.
And I will also upgrade all of my YouTube content to .NET 7.
P.S. Whenever you're ready, there are 2 ways I can help you:
Pragmatic Clean Architecture: This comprehensive course will teach you the system I use to ship production-ready applications using Clean Architecture. Learn how to apply the best practices of modern software architecture. Join 950+ students here.
Patreon Community: Think like a senior software engineer with access to the source code I use in my YouTube videos and exclusive discounts for my courses. Join 820+ engineers here.