简体   繁体   English

可为空的泛型引用类型

[英]Nullable generic reference type

I have the following (working) service implemented using C#8, but with nullable reference types disabled:我使用 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 */ }
}

I tried to enable C#8 nullable reference types, but can't seem to get rid of errors or warnings, whatever I do.我尝试启用 C#8 可空引用类型,但无论我做什么,似乎都无法摆脱错误或警告。 The new interface type is:新的接口类型是:

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;
}

When I use the following implementation:当我使用以下实现时:

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

I get the error:我得到错误:

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

Which I don't understand because the signatures in the interface and in the implementation are exactly the same.我不明白,因为接口和实现中的签名完全相同。

However, when I implement the interface as this (which is the signature Visual Studio's auto-implementation generates):但是,当我这样实现接口时(这是 Visual Studio 的自动实现生成的签名):

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

I get the following warning:我收到以下警告:

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

You need to add the generic constraint to your implementation:您需要将通用约束添加到您的实现中:

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

It's interesting how Visual Studio doesn't add the T?有趣的是,Visual Studio 如何不添加T? to the implementation it generates.到它生成的实现。 I suspect this is a bug in the editor.我怀疑这是编辑器中的错误。

You mention that your type constriant is actually against a Foo .您提到您的类型约束实际上是针对Foo的。 This means your code would look like this:这意味着您的代码将如下所示:

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();
    }
}

The type constraint is on the interface, but on the implemetation you can't specify an actual type name, but you can indicate it has to be a class.类型约束在接口上,但在实现上你不能指定实际的类型名称,但你可以指出它必须是 class。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM