VB.NET中是否有类似于C#的'??'运算符的等效操作符?

202

是否有VB.NET相当于C#中的 ?? 运算符的等效操作符?


4
这里的大部分答案(包括被采纳的答案)都是不正确的,并且在所有情况下都不能与 ?? 功能等效。正确的等效语句是带有两个参数的 if() 语句。然而,第二个参数可以嵌套,以达到与具有多个参数的 ?? 完全相同的结果。 - user1751825
你是指三元运算符 ?: 吗?例如,返回 ((value < 0)?true:false)。 - Zeek2
6个回答

176

使用带有两个参数的If()运算符 (Microsoft文档):

' Variable first is a nullable type.
Dim first? As Integer = 3
Dim second As Integer = 6

' Variable first <> Nothing, so its value, 3, is returned.
Console.WriteLine(If(first, second))

second = Nothing
' Variable first <> Nothing, so the value of first is returned again. 
Console.WriteLine(If(first, second))

first = Nothing second = 6
' Variable first = Nothing, so 6 is returned.
Console.WriteLine(If(first, second))

5
我认为VB中的If()语句与C#中的if...?...:相同,而不是??运算符。 - Luke T O'Brien
3
如果您使用三个参数,则是这样的。如果您使用两个参数,则它比 ?? 更多(请参见此问题的另一个答案:https://dev59.com/FHRC5IYBdhLWcg3wG9bp#20686360)。 - Brian J
2
这个答案展示了如何使用VB的带有三个参数的If语句。这与C#的??运算符不同。更好的答案是Code Maverick的带有两个参数的If语句。(Nick在几年前也给出了类似的答案,但没有包含MSDN的解释。) - ToolmakerSteve
1
这个回答完全不相关。 - Marc Gravell
5
查看之前的评论,请查看编辑历史。 - Zev Spitz
显示剩余2条评论

110

3
这个链接(实际上)已经失效了。 - Peter Mortensen
Code Maverick的后续回答提供了MSDN的解释和更详细的示例。 - ToolmakerSteve

75

被接受的答案没有任何解释,只是一个链接。
因此,我想留下一个答案,从MSDN中解释了If运算符的工作原理:


If 运算符 (Visual Basic)

Uses short-circuit evaluation to conditionally return one of two values. The If operator can be called with three arguments or with two arguments.

If( [argument1,] argument2, argument3 )


如果用两个参数调用If运算符

可以省略对If的第一个参数。这使得运算符可以仅使用两个参数进行调用。以下列表适用于仅使用两个参数调用If运算符。


部件

Term         Definition
----         ----------

argument2    Required. Object. Must be a reference or nullable type. 
             Evaluated and returned when it evaluates to anything 
             other than Nothing.

argument3    Required. Object.
             Evaluated and returned if argument2 evaluates to Nothing.

当省略Boolean参数时,第一个参数必须是引用类型或可空类型。如果第一个参数为 Nothing,则返回第二个参数的值。在所有其他情况下,返回第一个参数的值。以下示例说明了此评估如何工作。

VB

' Variable first is a nullable type. 
Dim first? As Integer = 3
Dim second As Integer = 6

' Variable first <> Nothing, so its value, 3, is returned.
Console.WriteLine(If(first, second))

second = Nothing 
' Variable first <> Nothing, so the value of first is returned again.
Console.WriteLine(If(first, second))

first = Nothing
second = 6
' Variable first = Nothing, so 6 is returned.
Console.WriteLine(If(first, second))

处理超过两个值的示例(嵌套的if语句)的方法如下:
Dim first? As Integer = Nothing
Dim second? As Integer = Nothing
Dim third? As Integer = 6
' The LAST parameter doesn't have to be nullable.
'Alternative: Dim third As Integer = 6

' Writes "6", because the first two values are "Nothing".
Console.WriteLine(If(first, If(second, third)))

20
您可以使用扩展方法。这个方法类似于SQL中的COALESCE,可能对于您尝试测试的内容来说有些过度,但它是有效的。
    ''' <summary>
    ''' Returns the first non-null T based on a collection of the root object and the args.
    ''' </summary>
    ''' <param name="obj"></param>
    ''' <param name="args"></param>
    ''' <returns></returns>
    ''' <remarks>Usage
    ''' Dim val as String = "MyVal"
    ''' Dim result as String = val.Coalesce(String.Empty)
    ''' *** returns "MyVal"
    '''
    ''' val = Nothing
    ''' result = val.Coalesce(String.Empty, "MyVal", "YourVal")
    ''' *** returns String.Empty
    '''
    ''' </remarks>
    <System.Runtime.CompilerServices.Extension()> _
    Public Function Coalesce(Of T)(ByVal obj As T, ByVal ParamArray args() As T) As T

        If obj IsNot Nothing Then
            Return obj
        End If

        Dim arg As T
        For Each arg In args
            If arg IsNot Nothing Then
                Return arg
            End If
        Next

        Return Nothing

    End Function

内置的If(nullable, secondChoice)只能处理两个可空选项。在这里,可以Coalesce尽可能多的参数。将返回第一个非空参数,之后不会评估其余参数(短路,类似于AndAlso/&&OrElse/||


9
因为该语言内置了操作符,所以甚至不需要查看扩展方法。 - Nick
3
我不会重复别人的答案。我认为,如果您需要在一个语句中检查多个值,提供另一种解决方案可能会很好。既然它并不是一个错误的答案,那么它是否应该被点踩? - StingyJack
1
提供一个使用泛型并避免类型转换/装箱/拆箱的实现,+1。 - ulty4life
4
@Nick,抱歉,但你是完全错误的。如果你有超过两个的coalesce参数,内置函数将不能胜任。 - toddmo
1
您可以跳过obj参数并让body为Return args.FirstOrDefault(Function(arg) arg IsNot Nothing) :-) - Ulf Åkerstedt
显示剩余6条评论

13

大多数这些解决方案的一个显著限制是它们不会短路。因此,它们实际上并不等同于 ??

内置的 If 运算符仅在前面的参数求值为无效时,才计算后续参数。

以下语句等效:

C#

var value = expression1 ?? expression2 ?? expression3 ?? expression4;

VB

dim value = if(expression1,if(expression2,if(expression3,expression4)))

这将适用于所有??适用的情况。任何其他解决方案都必须极度谨慎地使用,因为它们可能轻易引入运行时错误。


在存在未知数量的参数的情况下,这种方法无法工作(嗯...除非使用Roslyn或CodeDom预编译语句以匹配执行时的参数数量)。 - StingyJack
@StingyJack 这并不是它的意图。它正好做了 ?? 运算符所做的事情。 - user1751825

3

请查看微软文档,了解If操作符(Visual Basic)的详细信息: https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/operators/if-operator

If( [argument1,] argument2, argument3 )

这里有一些例子(VB.Net):
' This statement prints TruePart, because the first argument is true.
Console.WriteLine(If(True, "TruePart", "FalsePart"))

' This statement prints FalsePart, because the first argument is false.
Console.WriteLine(If(False, "TruePart", "FalsePart"))

Dim number = 3
' With number set to 3, this statement prints Positive.
Console.WriteLine(If(number >= 0, "Positive", "Negative"))

number = -1
' With number set to -1, this statement prints Negative.
Console.WriteLine(If(number >= 0, "Positive", "Negative"))

1
不错!移除注释! - cela

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接