可空类型和内联if不能一起使用?

7

假设有以下代码:

Dim widthStr As String = Nothing

这个有效 - width 被赋值为 Nothing:
Dim width As Nullable(Of Double)
If widthStr Is Nothing Then
  width = Nothing
Else
  width = CDbl(widthStr)
End If

但是这样做不会起作用 - width 变成了 0.0(尽管代码在逻辑上看起来是相同的):

Dim width As Nullable(Of Double) = If(widthStr Is Nothing, Nothing, CDbl(widthStr))

为什么会这样?有什么我可以做的来使它工作吗?

你尝试在C#中使用相同的代码了吗?double? width = widthStr != null ? Double.Parse(widthStr) : (double?)null; - Federico Berasategui
请查看以下与编程有关的内容:https://dev59.com/723Xa4cB1Zd3GeqPkOtU http://stackoverflow.com/questions/2647558/preserving-null-values-in-a-double-variable - spajce
2
@HighCore - 在C#中,null和VB.Net中的Nothing不等价的。Nothing大约相当于default(T) - Damien_The_Unbeliever
2个回答

12

除了Damien的回答之外,更加规范的做法是不要使用Nothing,而是使用New Double?

Dim width As Double? = If(widthStr Is Nothing, New Double?, CDbl(widthStr))

现在,如果If表达式的类型是正确的,那么它可以简化为:

Dim width = If(widthStr Is Nothing, New Double?, CDbl(widthStr))

+1。感谢您的建议。为了代码清晰,我通常不使用任何特殊字符。因此,Dim width As Nullable(Of Double) = If(widthStr Is Nothing, New Nullable(Of Double), CDbl(widthStr)) 更可取。 - Victor Zakharov
我理解您不想使用“特殊字符”的偏好(对于变量,我也不会使用任何类型的字符 - 但对于常量,我会使用)。但在这种情况下,IDE会引发错误,涉及到Nullable(Of)?形式。 - Mark Hurd
不,只是在处理使用 Nullable(Of Something) 代码的错误时,VB.NET 编译器会引用 Something? - Mark Hurd

5
这一切归结于表达式的类型分析。
在VB.Net中,Nothing并不神秘。它与C#中的default(T)几乎相同。
因此,在尝试确定以下内容的最佳类型时:
If(widthStr Is Nothing, Nothing, CDbl(widthStr))

第三个参数的类型为Double。第二个参数可以转换为Double(因为Nothing可以返回值类型的默认值)。因此,If的返回值类型确定为Double
只有在完成这种类型分析之后,才会关注将此表达式分配给的变量的类型。而Double可以无警告地分配给Double?
没有一种干净的方法使您的If()表达式按照您的预期工作。因为在VB.Net中没有等效于null的内容。您需要(至少)在If的潜在结果的一侧或另一侧插入DirectCast(或等效内容),以强制类型分析看到Double?而不是Double

+1,尽管我不认为我完全理解你的答案。你是在暗示这样的内联If在幕后是一个通用函数吗?这就是VS用于推断其类型的方式吗? - Victor Zakharov
@Neolisk - 我自从第一次发布以来已经编辑了几次我的问题 - 你读过最新版本吗?If不是通用函数。但是,正如我所说,Nothing是一个神奇的生物。它本身是无类型的,因此任何其他类型信息都将首先使用。 - Damien_The_Unbeliever
有趣的是,尽管我希望类型分析考虑等式左侧的类型,但无论如何,感谢您提供如此详尽的解释。 - Victor Zakharov
@Neolisk - 经常情况下,没有左侧(考虑没有类型的 Dim,任何子表达式或用作函数参数 - 它必须确定表达式结果的类型,然后才能确定调用哪个重载)。 - Damien_The_Unbeliever

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接