Nullables的隐式界面演员

时间:2012-09-20 01:37:59

标签: vb.net interface nullable implicit-conversion

使用VB的Option Strict On,为什么Nullable(Of T)在需要一个T时,不需要对T的接口进行显式强制转换?

Dim x As Integer? = 5
Dim y As Integer
Dim z As IComparable

y = x ' Fails to compile with error
      ' "Option Strict On disallows implicit conversions from 'Integer?' to 'Integer'."
z = x ' Succeeds
编辑:@SSS显示的(有点),部分答案是Nullable值是,可以为空,可以是Nothing,这对于像接口。因此转换将始终成功,不像转换为T情况(当Nullable没有值时失败),因此可以将其视为隐式转换。

我现在的问题变成“如何?”。如何从Nullable(Of T)(没有自己的接口)到理论上协商的T接口的转换?

我知道实现是box Nullable<T>,它有效地删除了Nullable包装器,但我在这里确认了这个概念......

(所以我会查看文档,看看他们是否解释了这一点。)

3 个答案:

答案 0 :(得分:1)

我没有看到问题?

y = x 

可能会失败,因为x可以保存Nothing值,但不允许y保持Nothing值。 IComparable接口允许将整数与Nothing进行比较,因此分配很好。

请注意,如果你换掉它:

x = y

然后这成功,因为y的每个值都可以分配给x。

您可以确认可以将整数与Nothing进行比较,如下所示:

MsgBox(5.CompareTo(Nothing))

答案 1 :(得分:0)

从我在vb.net中可以看出,语句interfaceVariable = nullableVariable基本上等同于interfaceVariable = if(nullableVariable.HasValue, CType(nullableVariable.Value, interfaceType), Nothing)。 C#编译器似乎以相同的方式处理事情:interfaceVariable = nullableVariable;变为interfaceVariable = nullableVariable.HasValue ? (interfaceType)nullableVariable.Value : null;

如果nullableValue.Value的类型实现了接口,那么nullableVariable.Value将执行返回值类型结果或抛出异常。由于存在从返回值到界面的保证拳击转换,因此演员表是合法的。上述代码失败的唯一方法是,如果在HasValueValue的调用之间写入可空变量,则HasValue将变量视为非空,但是{{1将它视为null并抛出异常。我相信写Value只测试一次无效,这样就不会发生异常;相反,一个不确定的值将被装箱。

答案 2 :(得分:0)

如果没有真正阅读文档,我将尝试回答:

首先,更高级别的答案是将Nullable转换为接口是“安全的”并且不会抛出,因此它在逻辑上是Widening运算符,不应该是显式的(与投射到T相比,当.HasValueFalse时它会抛出,因此不应该隐含Option Strict On)。

然而,从技术上来说,“如何”有点模糊:尽管Nullable的某些行为是通过反射提供的元数据中编码的,但它的大部分“魔法”都隐藏在:

  • boxNullable的运行时行为(因此编译器知道何时离开“提升”),
  • Eric Lippert在他的answer for C#中提出的其他观点及其在VB.NET中的等价点。

看起来S. Somasegar's blog post宣布对VS2k5的后期测试版Nullable支持的更改也与此相关。