6

我在使用在 VB.NET 中返回 Nothing 的结构和函数时有些头疼。

让我试着用这段代码在这里解释一下:

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

在前面的代码中,当我返回 Nothing 作为 Foo 函数的结果时,我希望stNothing。但这不是发生的事情。

然后我在 MSDN 文档中找到:

将 Nothing 分配给变量会将其设置为其声明类型的默认值。如果该类型包含变量成员,则它们都设置为其默认值。

所以我发现当我将Nothing分配给一个结构时,它的所有成员都设置为它们的默认值,而不是结构本身。

另外,我试图通过声明使st成为 Nullable 类型:

    Dim st As Nullable(Of Test) = Foo()  

但是,我仍然无法通过以下方式检查st是否为 Nothing:

    If st Is Nothing Then  

或者

    If st.Equals(Nothing) Then

所以,问题:
1 - 是否可以将Nothing分配给结构而不是其成员?
2 - 如何检查返回结构值是否为Nothing

4

3 回答 3

19

结构是一种值类型,它不能是 Nothing。Nullable 类型可以解决你的问题,在类型名称后面加上一个问号,让它简短明快。这是一个例子:

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
于 2010-07-02T21:00:27.563 回答
13

以下前两种方法在 .NET Framework 中经常使用。您使用的方法将取决于您的要求。如果结构不经常测试,我将使用方法#3。对于频繁的测试,如果方法 #2 不适合“空”测试,我将使用方法 #1。例如,该Point结构将一个空点定义为 {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

方法 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.IsEmpty Then

方法三:使用 Nullable(Of T)

定义为:

Dim st As Test? = Foo() 
'--or--
Dim st As Nullable(Of Test) = Foo()

测试为:

If st Is Nothing Then
'--or--
If st.HasValue = False Then

笔记

我没有测试上面的代码,也没有访问我的代码库的权限。

灵感

看看微软的PointColor结构,使用他们发布的源代码或使用.NET Reflector

于 2010-07-02T21:04:18.897 回答
0

没有分配“没有给结构而不是它的成员”这样的概念。

这听起来很像您应该查看可空值类型,并且Nullable(Of T)- 如果您需要能够表示值类型不存在“真实”值,这正是它被发明的原因。

例如考虑Byte。一个Byte值可以有 256 个值 (0-255) 中的任何一个。如果您为其分配 value Nothing,那实际上会将其设为 0。它不能将其设为“不在 0-255 范围内的某个值”,因为它将被存储为 byte。我认为 VB确实让你Nothing在这里使用有点不幸,实际上......因为从哲学上讲,“缺失”值和值 0 确实是非常不同的东西。

无论如何,可空值类型包装“正常”值类型并提供额外的布尔值来说明是否真的存在有用的值。

于 2010-07-02T20:51:45.263 回答