在 Visual Basic.Net 中加零与无之间的区别?

问题描述 投票:0回答:2

为什么会不一样?!

Public Class Form1
 Public Function MyFunction() As Integer?
    Return Nothing
 End Function

 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Dim o As Object = Me
    MsgBox(TypeName(Me)) ' Form1
    MsgBox(TypeName(o))  ' Form1
    MsgBox(TypeName(Me.MyFunction())) ' Nothing
    MsgBox(TypeName(o.MyFunction()))  ' Nothing
    ' but
    MsgBox(TypeName(Me.MyFunction() + 0)) ' Nothing
    MsgBox(TypeName(o.MyFunction() + 0))  ' Integer
 End Sub
End Class
vb.net object
2个回答
4
投票

使用

Option Strict On
是避免此类意外的好方法。你会得到一个“你到底想做什么?”来自编译器的错误消息。

但关闭后,这些都是有效的语句,由 DLR(动态语言运行时)执行。它能够评估像这样的后期绑定表达式。然而,它对于像

Integer?
这样的可空类型有一个问题。它需要处理值的boxed版本。这根本就是什么都没有。 Nothing 没有任何与之关联的类型信息。 DLR 无法采取任何措施来查看这个以可为空整数开始的生命周期,因为它知道它可能是一个“Nothing”的string

编译器也无能为力,它无法发出任何代码来使表达式遵循正常的求值规则。它只知道有一个 some 函数,但它不知道是哪个函数,其名称是“MyFunction”,也不知道它返回什么样的值。它把责任推给 DLR 来解决。

所以德国航天中心只是押注它。它得出“不知道”+ 0 = 0。鉴于它确实具有0的类型信息。它是一个整数,因此它也尝试将左运算符解释为整数。这是有效的,Nothing 是 Integer 的正确默认值。

功能,而不是错误。


2
投票

Visual Basic .NET 早在拥有可空值类型之前就已经拥有

Nothing
- 它从 .NET 之前的 Visual Basic 继承了它。在某些情况下,它的行为更像 C# 的
default(T)
,然后 t 则
null

您的最后一个调用是调用 Visual Basic 编译器服务中的

AddObject
方法。这种方法已经存在很长时间了,并且再次早于可为空值类型,不幸的是没有很好的记录。

不幸的是,他们无法使可空类型的行为绝对一致,特别是在面对后期绑定调用时,同时仍然保持向后兼容性。例如,这也会打印

0
:

Console.WriteLine(CType(CType(Nothing, Object), Int32))
© www.soinside.com 2019 - 2024. All rights reserved.