public abstract record Result<T, ErrorT>
{
private Result() { }
public sealed record Ok(T result) : Result<T, ErrorT>;
public sealed record Error(ErrorT error) : Result<T, ErrorT>;
}
public interface IValid<T>
{
T Value { get; init; }
abstract static IEnumerable<string> Validate(T obj);
abstract static Result<IValid<T>, IEnumerable<string>> Create(T value);
}
I am trying to create a validation pattern that creates validated values of type T. But the Create function throws a compiler error CS8920
The interface Valid cannot be used as type argument
Any reason why this is not allowed and is there a way around this?
Example usage of this would be
public record DriverLicense : IValid<string>
{
public string Value { get; init; } = null!;
private DriverLicense() { }
public static Result<DriverLicense, IEnumerable<string>> Create(string licenseNumber){...}
public static IEnumerable<string> Validate(string licenseNumber){...}
}
This code alone:
did compile when they first added static abstract interface members, as can be seen on SharpLab, if you select the "C# Next: Static Abstract Members In Interfaces" branch.
However, this signature for
Createis not what you actually mean. Your intended implementation doesn't actually implementCreate:Notice that the return types are different, unrelated types. The type parameters of records are invariant. This would not have compiled in any version of C#.
What you actually meant is:
See also:
My guess is that they changed it in a later version, so that an error message would now show up as soon as you try to write the incorrect interface, rather than show the "does not implement this method" error when you write the implementation later down the line.