可空泛型引用类型

Nullable generic reference type

我使用 C#8 实现了以下(有效)服务,但禁用了可空引用类型:

public class Foo { }

public interface IFooService
{
    Task<T> Get<T>() where T : Foo;
}

public FooService : IFooService
{
    async Task<T> IFooService.Get<T>() { /* returns either a valid Foo implementation or null */ }
}

我尝试启用 C#8 可为空的引用类型,但似乎无法摆脱错误或警告,无论我做什么。新接口类型为:

public interface IFooService
{
    // T IS nullable AND a reference type.
    // There is no ambiguity as of 'T?' meaning here, because it can't be a struct.
    Task<T?> Get<T>() where T : Foo;
}

当我使用以下实现时:

public class FooService : IFooService
{
    async Task<T?> IFooService.Get<T>() { /* ... */ }
}

我收到错误:

'FooService' does not implement interface member 'IFooService.Get<T>()'

我不明白,因为接口和实现中的签名完全相同。

但是,当我这样实现接口时(签名 Visual Studio 的自动实现生成):

public class FooService : IFooService
{
    async Task<T> IFooService.Get<T>() { /* ... */ }
}

我收到以下警告:

Nullability of reference types in return type doesn't match implemented member 'Task<T?> IFooService.Get<T>()'.

您需要将通用约束添加到您的实现中:

public class FooService : IFooService
{
    async Task<T?> IFooService.Get<T>() where T : class
    {
        /* ... */ 
    }
}

有趣的是 Visual Studio 没有将 T? 添加到它生成的实现中。我怀疑这是编辑器中的错误。

您提到您的类型限制实际上反对 Foo。这意味着您的代码将如下所示:

public class Foo
{
}

public interface IFooService
{
    // T IS nullable AND a reference type.
    // There is no ambiguity as of 'T?' meaning here, because it can't be a struct.
    Task<T?> Get<T>() where T : Foo;
}

public class FooService : IFooService
{
    async Task<T?> IFooService.Get<T>() where T : class
    {
        throw new NotImplementedException();
    }
}

类型约束在接口上,但在实现上您不能指定实际的类型名称,但您可以指示它必须是 class。