为什么接口不能用作类型参数?


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) {...}
}

另请参阅:

  • 奇怪的重复模板模式
  • 类似的问题

我的猜测是他们在后来的版本中更改了它,这样,当你试图编写不正确的界面时,就会出现错误消息,而不是显示";不实现这种方法";稍后编写实现时出错。

最新更新