---
title: "static abstract interfaces and generic math"
description: "Besides the big announcements of .NET 6 there are also some smaller features. I want to show case a special one: **static abstract interfaces**. With this you have ability to extend the contract in that sense, that an implementing class has to provide also static methods.\nThis feature is right now flagged as preview, but you can use it if you want.\n\nThis also enables generic math operations on an interface level.\n"
updated: 2021-10-17
tags: ["preview", "generic math", "c#", ".net", "interfaces"]
canonical: "https://steven-giesel.com/blogPost/f3de9085-aa03-46c3-99d6-e857bb9ceb6c/static-abstract-interfaces-and-generic-math"
---

# static abstract interfaces and generic math

In case you missed the announcment. here it is; [Preview Features in .NET6](https://devblogs.microsoft.com/dotnet/preview-features-in-net-6-generic-math/#static-abstracts-in-interfaces). What does it do? Well we now have the ability to declare static abstract function as an contract either on your interfaces.

By the way: To add preview features is a very nice way to get early feedback. I like the approach very much.

## Let's go
Where does it come in handy? You remember all those `Parse` or `TryParse` method on some value types. Just imagine you want to have that on your own data type. Now you can do it:

### Setup
Before we dive in, we have to enable the preview features in our csproj file. Add `<EnablePreviewFeatures>true</EnablePreviewFeatures>` and `<LangVersion>preview</LangVersion>` to any `PropertyGroup`. For example
```
<PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <LangVersion>preview</LangVersion>
    <EnablePreviewFeatures>true</EnablePreviewFeatures>
</PropertyGroup>
```

You can use Rider 2021.2 or Visual 2019 but be aware, that even though the code will compile your IDE will go havoc on you as it doesn't know the feature.
For best experience either use Visual Studio 2022 Preview or Rider EAP.

## Example

```csharp
public interface IParseable<T>
{
    static abstract T Zero { get; }
    static abstract T Parse(string from);
    static abstract bool TryParse(string from, out T obj);
}
```

Now if we derive from that interface we have to implement all those static functions as well:
```csharp
public class MyBetterGuid : IParsable<MyBetterGuid>
{
    private long _internalGuid;

    public static MyBetterGuid Zero => throw new NotImplementedException();

    public static MyBetterGuid Parse(string from)
    {
        throw new NotImplementedException();
    }

    public static bool TryParse(string from, out MyBetterGuid value)
    {
        throw new NotImplementedException();
    }
}
```

### Current Design "limitations"
* Does not work with default interface methods introduced in C# 8 (`static virtual` is not a valid combination)
* Only available on interfaces and not on (abstract) classes
* Not accessible via the interface (`IParsable<MyBetterGuid>.Parse("123");` is forbidden - as they are static there is no object to invoke)

## Generic Math
Now this is a huge enables for generic math. All operators like `+`, `-` are defined as static operations on a class. Now we can leverage this to introduce this on an interface level.
But where is the benefit: Have a look at the following
```csharp
public int Sum(IEnumerable<int> source)
{
    int sum = default;
    foreach (var s in source)
    {
        sum = sum + s;
    }

    return sum;
}
```

This works without any problem. So what happens if we introduce generic?
```csharp
public T Sum<T>(IEnumerable<T> source) 
{
    T sum = default;
    foreach(var s in source)
    {
        sum = sum + s;
    }

    return sum;
}
```
Well, that doesn't compile anymore because the compiler can't apply the `operator +` to the operands.
But why can it do so for `IEnumerable<int>`? Well because LINQ brings some functions with it exactly for that reason:
```csharp
public static partial class Enumerable {
    public static int Sum(this IEnumerable<int> source) { ... }
```

But now we have the ability to make it work with static abstract interfaces!
We just need to define this operator on an interface level and use it in our function:
```csharp
public interface IAdditionOperators<TSelf>
where TSelf : IAdditionOperators<TSelf>
{
    static abstract TSelf operator +(TSelf left, TSelf right);
}

public class MyBetterGuid : IAdditionOperators<MyBetterGuid>
{
    public static MyBetterGuid operator +(MyBetterGuid left, MyBetterGuid right)
    {
        // ...
    }
}
```

And now we just use it in our sum function from above. But this time we explicitly constraining the method to our interface.
```csharp
public T Sum<T>(IEnumerable<T> source) where T : IAdditionOperators<T>
{
    T sum = default;
    foreach(var s in source)
    {
        sum = sum + s;
    }

    return sum;
}
```
That works like a charm!

## Conclusion
With the new Preview features `static abstract` interfaces and generic math we get some powerful tools in our hands to write code.
Also I love the choice of the .NET team to make them available as a preview to gather quick feedback!