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);
}
我正试图创建一个验证模式来创建T类型的验证值。但是Create
函数抛出了一个编译器错误CS8920
接口Valid不能用作类型参数
为什么不允许这样做?有办法解决吗?
例如
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){...}
}
仅此代码:
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);
}
当他们第一次添加静态抽象接口成员时进行了编译,如SharpLab上所示,如果您选择";C#下一篇:接口中的静态抽象成员";树枝
然而,Create
的这个签名并不是您的实际意思。您预期的实现实际上并没有实现Create
:
// interface
abstract static Result<IValid<T>, IEnumerable<string>> Create(T value);
// implementation
public static Result<DriverLicense, IEnumerable<string>> Create(string licenseNumber){}
请注意,返回类型是不同的、不相关的类型。记录的类型参数是不变的。这不会在任何版本的C#中编译。
你的实际意思是:
public interface IValid<TSelf, T> where TSelf: IValid<TSelf, T>
{
...
abstract static Result<TSelf, IEnumerable<string>> Create(T value);
}
public record DriverLicense : IValid<DriverLicense, string>
{
...
public static Result<DriverLicense, IEnumerable<string>> Create(string licenseNumber) {...}
}
另请参阅:
- 奇怪的重复模板模式
- 类似的问题
我的猜测是他们在后来的版本中更改了它,这样,当你试图编写不正确的界面时,就会出现错误消息,而不是显示";不实现这种方法";稍后编写实现时出错。