在Visual Basic.Net中添加零到零之间的区别?

时间:2014-12-18 11:16:54

标签: vb.net object nothing

为什么会有所不同?!

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

2 个答案:

答案 0 :(得分:4)

使用Option Strict On是一种避免这样的惊喜的好方法。你会得到一个“你想要做什么?”来自编译器的错误消息。

但是当它关​​闭时,这些是由DLR(动态语言运行时)执行的有效语句。哪个能够评估这样的后期绑定表达式。但是它有像Integer?这样的可空类型的问题。它需要处理值的盒装版本。这简直就是没什么。并且没有任何类型信息与之相关。 DLR没有什么可以看到这开始是一个可以为空的整数生命,因为它知道它可能是字符串是Nothing。

编译器也无法帮助,它不能发出任何代码使表达式遵循正常的评估规则。它只知道有一些函数,它不知道哪个,其名称是“MyFunction”,不知道它返回的是什么类型的值。它将降压传递给DLR以对其进行排序。

所以DLR就是这样做的。并且它提出“不知道”+ 0 = 0.假设它 具有0的类型信息。它是一个整数,所以它也试图将左运算符解释为整数。哪个是有效的,没有什么是Integer的正确默认值。

功能,而不是错误。

答案 1 :(得分:2)

Visual Basic .NET在具有可空值类型之前已经有Nothing了 - 它从pre-.NET Visual Basic继承了它。在某些情况下,它的行为更像是C#' default(T)然后t null

您的最后一个调用是调用Visual Basic编译器服务中的AddObject方法。这种方法已经存在了很长时间,并且再次提出了可以为空的值类型,并且遗憾的是没有很好地记录。

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

Console.WriteLine(CType(CType(Nothing, Object), Int32))