具有通用返回类型的可空引用类型 [英] Nullable reference types with generic return type
问题描述
我正在使用新的C#8可为空的引用类型功能,并且在重构代码时遇到了这种(简化的)方法:
I'm playing around a bit with the new C# 8 nullable reference types feature, and while refactoring my code I came upon this (simplified) method:
public T Get<T>(string key)
{
var wrapper = cacheService.Get(key);
return wrapper.HasValue ? Deserialize<T>(wrapper) : default;
}
现在,这会给出警告Possible null reference return
,这是合乎逻辑的,因为default(T)
将为所有引用类型提供null.一开始我以为可以将其更改为以下内容:
Now, this gives a warning Possible null reference return
which is logical, since default(T)
will give null for all reference types. At first I thought I would change it to the following:
public T? Get<T>(string key)
但这无法完成.它说我必须添加通用约束where T : class
或where T : struct
.但这不是一个选择,因为两者都可以(我可以在缓存中存储int
或int?
或FooBar
的实例或其他内容).
我还读了关于所谓的新通用约束where class?
的信息,但这似乎行不通.
But this cannot be done. It says I either have to add a generic constraint where T : class
or where T : struct
. But that is not an option, as it can be both (I can store an int
or int?
or an instance of FooBar
or whatever in the cache).
I also read about a supposed new generic constraint where class?
but that did not seem to work.
我能想到的唯一简单的解决方案是使用 null宽容运算符来更改return语句:
The only simple solution I can think of is changing the return statement using a null forgiving operator:
return wrapper.HasValue ? Deserialize<T>(wrapper) : default!;
但是这感觉很不对,因为它肯定可以为null,所以我基本上在这里对编译器撒谎:-)
But that feels wrong, since it can definitely be null, so I'm basically lying to the compiler here :-)
我该如何解决?我在这里遗漏了一些显而易见的东西吗?
How can I fix this? Am I missing something utterly obvious here?
推荐答案
您非常亲密.只需这样编写您的方法:
You were very close. Just write your method like this:
[return: MaybeNull]
public T Get<T>(string key)
{
var wrapper = cacheService.Get(key);
return wrapper.HasValue ? Deserialize<T>(wrapper) : default!;
}
您必须使用default!
摆脱警告.但是您可以使用[return: MaybeNull]
告诉编译器,即使它是不可为null的类型,也应检查null.
You have to use the default!
to get rid of the warning. But you can tell the compiler with [return: MaybeNull]
that it should check for null even if it's a non-nullable type.
在这种情况下,如果开发人员使用您的方法并且不检查是否为空,则可能会得到警告(取决于流分析).
In that case, the dev may get a warning (depends on flow analytics) if he uses your method and does not check for null.
For further info, see Microsoft documentation: Specify post-conditions: MaybeNull and NotNull
这篇关于具有通用返回类型的可空引用类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!