I have the following (working) service implemented using C#8, but with nullable reference types disabled:
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. 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):
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?
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
. 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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.