Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
VB.NET结构和Nothing-问题_.net_Vb.net_Data Structures_Structure_Nothing - Fatal编程技术网

VB.NET结构和Nothing-问题

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

我在使用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 As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim st As Test = Foo()
    End Sub
End Class
在前面的代码中,当我作为Foo函数的结果返回Nothing时,我希望stNothing。但事实并非如此

然后我在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是对的,引用的副本已经制作好了。与将其复制到处理程序中相同。在鸡蛋没有以同样的方式煮熟之前,使用处理程序模式是样板。第一个方法要求对结构使用“=”运算符重载。另请参阅