带Nothing检查的变量声明

时间:2014-08-07 17:31:44

标签: vb.net

非常(经常)我们需要编写像

这样的东西
Dim Data = GetSomeData()
If Data IsNot Nothing Then
  Data.DoSomething()
Else
  ...
End If

也许我在徒劳地问,但我非常希望VB.Net有一些结构如:

IfExists Data = GetSomeData() Then
  Data.DoSomething()
Else
  ...
End IfExists

在我的梦中,它做了两件重要的事情:

  1. 没有额外的行没有检查
  2. 变量A在块外不可见,因此以后不能错误地使用(就像“使用”或“使用”)
  3. 有没有类似我尚未发现的东西?

    谢谢!

    编辑: 灵感来自Bjørn-RogerKringsjå的答案我想出了一些令我满意的东西(VB.Net的不足之处):

    <Extension()>
    Public Sub IfExists(Of T)(This As T, DoIfNotNothing As Action(Of T), Optional DoIfNothing As Action = Nothing)
        If This IsNot Nothing Then
            DoIfNotNothing(This)
        ElseIf DoIfNothing IsNot Nothing Then
            DoIfNothing()
        End If
    End Sub
    

    然后我可以像这样调用它(假部分是可选的)

    GetSomeData().IfExists(Sub(Data) Data.DoSomething())
    

    GetSomeData().IfExists(Sub(Data) Data.DoSomething(), Sub() DoSomethingElse())
    

3 个答案:

答案 0 :(得分:4)

正如其他人所说并且我暗示的那样,它无法完成。就像分享3'rd解决方案一样。这次我们将使用delegates

  1. 没有额外的行没有检查
  2. 变量A在块外不可见,因此以后无法使用。
  3. <强>实施

    Public Module Extensions
    
        Public Sub IfExists(Of T)(testExpr As T, trueDlg As Action(Of T), falseDlg As Action)
            If (Not testExpr Is Nothing) Then
                trueDlg.DynamicInvoke(New Object(0) {testExpr})
            Else
                falseDlg.DynamicInvoke(New Object(-1) {})
            End If
        End Sub
    
    End Module
    

    <强>用法

    IfExists(GetSomeData(),
             Sub(A As Object)
                 'We have something (A)
             End Sub,
             Sub()
                 'We have nothing
             End Sub
        )
    

    更短的:

    IfExists(GetSomeData(), Sub(A As Object)
                                    'We have something (A)
                                End Sub, Sub()
                                             'We have nothing
                                         End Sub)
    

    或者,最短的版本:

    IfExists(GetSomeData(), Sub(A As Object) Debug.WriteLine(A.ToString()), Sub() Debug.WriteLine("Nothing"))
    

答案 1 :(得分:1)

不,遗憾的是,目前在VB.NET中没有类似的东西。你可以做的最接近这种行为的方法是写一个这样的函数:

Public Function Assign(ByRef target As Object, value As Object) As Boolean
    target = value
    Return (target IsNot Nothing)
End Function

然后你可以像这样使用它:

Dim A As SomeType
If Assign(A, GetSomeData()) Then
    ' ...
Else
    ' ...
End If

但是,正如你所指出的那样,这并没有真正解决你所陈述的问题。它仍然是一行额外的代码,并且变量仍然没有作用域,只能在正确分配的块中访问。

答案 2 :(得分:0)

第一点是不可能的。无法声明变量并在单个语句中进行检查。

第二点有点可能。 VB.NET不支持创建自己的块作用域,但可以通过滥用其他块来实现。将代码插入一次性Loop While块中:

Do
    Dim A = GetSomeData()
    If A IsNot Nothing Then
        ...
    Else
        ...
    End If
Loop While False

将输入Do块,其中A在该块中声明为本地,然后该块将立即从While False退出,A将无法再访问

可能更好的简化方法是将代码重构为更小,更小的方法,以便If ... Else是整个方法,并且不可能在以后意外访问过时的变量。执行此操作时,您也可以在更简单的情况下从方法中提前退出,而不是同时保留IfElse分支:

    Dim A = GetSomeData()
    If A Is Nothing Then
        ...
        Exit Sub
    End If
    ...
End Sub