VB.NET结构和Nothing-问题
我在使用VB.NET中不返回任何内容的结构和函数时遇到了一些麻烦 让我试着用下面的代码来解释:VB.NET结构和Nothing-问题,.net,vb.net,data-structures,structure,nothing,.net,Vb.net,Data Structures,Structure,Nothing,我在使用VB.NET中不返回任何内容的结构和函数时遇到了一些麻烦 让我试着用下面的代码来解释: Public Class Form1 Structure Test Dim field1 As String End Structure Private Function Foo() As Test Return Nothing End Function Private Sub Form1_Load(ByVal sender
Public Class Form1
Structure Test
Dim field1 As String
End Structure
Private Function Foo() As Test
Return Nothing
End Function
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim st As Test = Foo()
End Sub
End Class
在前面的代码中,当我作为Foo函数的结果返回Nothing时,我希望st是Nothing。但事实并非如此
然后我在MSDN文档中发现:
不为变量赋值将其设置为其声明类型的默认值。如果该类型包含变量成员,则它们都设置为默认值
所以我发现当我给一个结构赋值时,它的所有成员都被设置为默认值,而不是结构本身
此外,我还试图通过声明以下内容使st成为可为空的类型:
Dim st As Nullable(Of Test) = Foo()
但是,我仍然无法使用以下命令检查st是否为空:
If st Is Nothing Then
或
所以,问题:1-是否可以不为结构分配任何内容,而不为其成员分配任何内容?
2-如何检查返回结构值是否为Nothing?没有“Nothing to the structure and Nothing to the members”这样的概念 这听起来很像你应该看到的——如果你需要能够表示一个值类型没有“真实”值,这正是它被发明的原因 例如,考虑
Byte
。字节
值可以有256个值(0-255)中的任意一个。如果将值赋值为Nothing
,则实际值为0。它不能使其成为“不在0-255范围内的某个值”,因为它将被存储为字节。我认为这有点不幸,VB确实允许您在这里使用什么都不使用
,实际上。。。因为从哲学上讲,“缺失”值和值0实际上是非常不同的东西
无论如何,可空值类型包装“普通”值类型,并提供一个额外的布尔值来说明是否存在真正有用的值。结构是一种值类型,它不能是空的。可为空的类型可以解决您的问题,在类型名称后加一个问号,使其简短而简洁。下面是一个例子:
Module Module1
Structure Test
Dim field1 As String
End Structure
Private Function Foo() As Test?
Return Nothing
End Function
Sub Main()
Dim st As Test? = Foo()
Debug.Assert(st is Nothing)
End Sub
End Module
在.NET Framework中经常使用以下前两种方法。您使用的方法将取决于您的要求。如果结构测试不频繁,我将使用方法#3。对于频繁测试,如果方法2不适合“空”测试,我将使用方法1。例如,
点
结构将空点定义为{x=0,y=0},我认为这是不正确的。因此,我将在点结构实现中使用第一种方法
方法1:为比较测试定义Empty
测试
添加共享的Test
以用于空比较
Structure Test
Public Shared Empty As Test = New Test
Dim field1 As String
End Structure
测试为:
If st = Test.Empty Then
If st.IsEmpty Then
If st Is Nothing Then
'--or--
If st.HasValue = False Then
方法2:为测试定义IsEmpty
属性
根据结构的内部状态定义IsEmpty
属性
Structure Test
Public ReadOnly Property IsEmpty As Boolean
Get
Return Len(field1) = 0
End Get
End Property
Dim field1 As String
End Structure
测试为:
If st = Test.Empty Then
If st.IsEmpty Then
If st Is Nothing Then
'--or--
If st.HasValue = False Then
方法3:使用Nullable(Of T)
定义为:
Dim st As Test? = Foo()
'--or--
Dim st As Nullable(Of Test) = Foo()
测试为:
If st = Test.Empty Then
If st.IsEmpty Then
If st Is Nothing Then
'--or--
If st.HasValue = False Then
注
我没有测试上述代码,也没有访问我的代码库的权限
灵感
使用Microsoft发布的源代码或.NET Reflector查看Microsoft的
Point
和Color
结构。?是可为空的(测试)
@hanspassant:不可能,你作弊。我的答案好多了!:O) 抱歉@miss,这是一个“只需添加一个问号”就可以将答案交给OP的问题。在接下来的10年里,你详细的回答肯定会比我得到更多的选票。不过,最好检查一下这是一个空泛的理论。@Hans Passant:在调用Invoke之前,你能不能先查看一下临时变量的赋值,并给出一个注释,以及为什么这是一个好主意。从我们几周前的一次交流中,我做了一个技术上不正确的评论,导致了一系列其他评论。@Amissio:dtb是对的,引用的副本已经制作好了。与将其复制到处理程序中相同。在鸡蛋没有以同样的方式煮熟之前,使用处理程序模式是样板。第一个方法要求对结构使用“=”运算符重载。另请参阅