What's New In .NET 7?
Tags: aspnetcore, dotnet, csharp
Published: 2023-09-10 08:01:40

---
title: What's New In .NET 7?
published: true
date: 2022-11-12 00:00:00 UTC
tags: aspnetcore,dotnet,csharp
canonical_url: https://www.milanjovanovic.tech/blog/whats-new-in-dotnet-7
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2mvazg7xf3hwa8ypi1es.png
---
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:

```csharp
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:

```csharp
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:

```csharp
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:

```csharp
[TypedAttribute(typeof(int))]
public int Method() => default;
```

Using the generic attributes feature, you can now define it like this:

```csharp
public class TypedAttribute<T> : Attribute { ... }
```

Now, we can specify the type parameter as a generic argument:

```csharp
[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.

```csharp
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:

```csharp
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 on[static abstract interface methods](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/static-virtual-interface-members#static-abstract-interface-methods)and [generic math](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/static-virtual-interface-members#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.

```csharp
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 an`IEnumerable`, which simplifies the code for sorting.

Here's an example of ordering an array:

```csharp
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:**

1. [**Pragmatic Clean Architecture:**](https://www.milanjovanovic.tech/pragmatic-clean-architecture?utm_source=dev.to&utm_medium=website&utm_campaign=cross-posting) 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.**](https://www.milanjovanovic.tech/pragmatic-clean-architecture?utm_source=dev.to&utm_medium=website&utm_campaign=cross-posting)

2. [**Patreon Community:**](https://www.patreon.com/milanjovanovic) 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.**](https://www.patreon.com/milanjovanovic)