Just a warning, this question requires a preview of .NET 6 to be installed
I'm trying to create an interface in C# that can allow the +
operator similar to how it is implemented in Microsoft's INumber<T>
.
Interfaces.cs
using System;
using System.Runtime.Versioning;
namespace InterfaceTest;
[RequiresPreviewFeatures]
public interface IExtendedArray<T> : IAdditionOperators<IExtendedArray<T>, IExtendedArray<T>, IExtendedArray<T>>
where T : INumber<T>
{
Array Data { get; }
}
[RequiresPreviewFeatures]
public interface IExtendedFloatingPointArray<T> : IExtendedArray<T>
where T : IFloatingPoint<T>
{
}
InterfaceTest.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<EnablePreviewFeatures>true</EnablePreviewFeatures>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>false</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Runtime.Experimental" Version="6.0.0-preview.7.21377.19" />
</ItemGroup>
</Project>
However, this code produces
error CS8920: The interface 'InterfaceTest.IExtendedArray' cannot be used as type parameter 'TSelf' in the generic type or method 'IAdditionOperators<TSelf, TOther, TResult>'. The constraint interface 'System.IAdditionOperators<InterfaceTest.IExtendedArray, InterfaceTest.IExtendedArray, InterfaceTest.IExtendedArray>' or its base interface has static abstract members.
Is there a way achieve this with custom types?
dotnet --list-sdks
shows I have 6.0.100-rc.1.21458.32
installed. But I just had it installed through the Visual Studio 2022 Preview 4.
Finally I was able to reproduce your issue - needed to install VS 2022 preview (2019 version compiled code just fine but failed in the runtime) or use dotnet build
from terminal.
If you want to do something similar with INumber
you need to follow the same pattern with TSelf
type reference (if I'm not mistaken it is called curiously recurring template pattern):
[RequiresPreviewFeatures]
public interface IExtendedArray<TSelf, T> : IAdditionOperators<TSelf, TSelf, TSelf> where TSelf : IExtendedArray<TSelf, T> where T : INumber<T>
{
T[] Data { get; }
}
[RequiresPreviewFeatures]
public interface IExtendedFloatingPointArray<TSelf, T> : IExtendedArray<TSelf, T>
where TSelf : IExtendedFloatingPointArray<TSelf, T>
where T : IFloatingPoint<T>
{
}