【发布时间】:2019-04-04 22:58:40
【问题描述】:
我正在尝试将一些代码移植到 C# 以启用可为空的引用类型,并且我在代码中遇到了一些使用 TryGetValue 模式的函数。
也就是说,是这样的:
public bool TryGetSession(string key, out Session session) {
session = null; // assign default
// code which looks for a session based on the key, etc
// return true or false if we found the session key
}
我们在这里试图表达的模式是“如果返回值为真,那么session 是非空的。如果为假,那么甚至不要尝试查看会话,这是垃圾。
问题是我现在在 session = null 上收到警告,但我不得不将 something 放在那里,因为 out 参数必须由函数填充。
这里有好的答案吗?我的想法:
我可以放弃 TryGet 模式并采用可为空的引用类型(这是 Swift 等其他语言似乎所做的),例如
Session? GetSession(string key);
或者,我可以使用占位符值来兑现我的“非空”承诺,例如
public bool TryGetSession(string key, out Session session) {
session = new InvalidSession(); // assign default
...
}
还有其他选择吗?
【问题讨论】:
-
public bool TryGetSession(string key, out Session? session)不是表达这一点的合适方式吗?如果输出参数必须为非空,则“TryGet”实际上没有意义。 -
AFAIK,这是 !-operator 需要忽略警告的情况之一。我实际上设计了我的方法,比如
bool TryGetValue(TKey key, TValue? value)(因为他们就是这样做的),当然,在检查返回的布尔值之后,在调用代码中使用了value!。希望有更智能的东西! -
@madreflection
out Session?将是在 C# 类型系统中表达它的最佳方式,但是之后我必须显式地检查该值,或者使用!- 这两者不用做就好了 -
这是相当不幸。我知道这仍然是一个额外的步骤,但模式匹配对于 null 检查似乎相对惯用,并且可以内联完成:
if (TryGetSession(key, out Session? temp) && temp is Session session).