Gibt es ein VB.NET-Äquivalent für C # 's' ?? ' Operator?

180

Gibt es ein VB.NET-Äquivalent für den ??Operator von C # ?

Nathan Koop
quelle
4
Die meisten Antworten hier (einschließlich der akzeptierten Antwort) sind nicht korrekt und entsprechen funktional nicht ?? in allen Situationen. Das richtige Äquivalent ist die if () - Anweisung mit 2 Argumenten. Das zweite Argument kann jedoch verschachtelt werden, um genau die gleichen Ergebnisse wie ?? mit mehreren Argumenten.
user1751825
Meinen Sie den ternären Operator ?:
ZB

Antworten:

154

Verwenden Sie den If()Operator mit zwei Argumenten ( Microsoft-Dokumentation ):

' 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))
Firas Assaad
quelle
3
Ich denke, die If()Aussage in VB ist die gleiche wie if...?...:in C #, nicht der ??Operator
Luke T O'Brien
2
@ LukeTO'Brien Das ist, wenn Sie es mit 3 Argumenten verwenden. Wenn Sie es mit 2 Argumenten verwenden, ist es mehr als ??(siehe eine andere Antwort auf diese Frage: stackoverflow.com/a/20686360/1474939 )
Brian J
2
Diese Antwort zeigt, wie VB If mit drei Parametern verwendet wird . Das ist dem Operator von C # nicht ähnlich ??. Bessere Antwort ist Code Mavericks If mit zwei Argumenten . (Nick hatte Jahre zuvor eine ähnliche Antwort, enthält aber keine Erklärung von MSDN.)
ToolmakerSteve
1
Dies beantwortet eine ganz andere Frage.
Marc Gravell
1
Um die vorherigen Kommentare zu verstehen, sehen Sie sich den Bearbeitungsverlauf an.
Zev Spitz
70

Die akzeptierte Antwort hat keinerlei Erklärung und ist einfach nur ein Link.
Daher dachte ich, ich würde eine Antwort hinterlassen, die erklärt, wie der IfOperator aus MSDN funktioniert:


Wenn Operator (Visual Basic)

Verwendet die Kurzschlussauswertung, um einen von zwei Werten bedingt zurückzugeben. Der If- Operator kann mit drei Argumenten oder mit zwei Argumenten aufgerufen werden.

If( [argument1,] argument2, argument3 )


Wenn der Operator mit zwei Argumenten aufgerufen wird

Das erste Argument für If kann weggelassen werden. Dadurch kann der Operator mit nur zwei Argumenten aufgerufen werden. Die folgende Liste gilt nur, wenn der If- Operator mit zwei Argumenten aufgerufen wird.


Teile

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.


Wenn das Boolesche Argument weggelassen wird, muss das erste Argument eine Referenz oder ein nullbarer Typ sein. Wenn das erste Argument nichts ergibt, wird der Wert des zweiten Arguments zurückgegeben. In allen anderen Fällen wird der Wert des ersten Arguments zurückgegeben. Das folgende Beispiel zeigt, wie diese Auswertung funktioniert.


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))

Ein Beispiel für den Umgang mit mehr als zwei Werten (verschachtelte ifs):

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)))
Code Maverick
quelle
18

Sie können eine Erweiterungsmethode verwenden. Dieser funktioniert wie SQL COALESCEund ist wahrscheinlich übertrieben für das, was Sie testen möchten, aber er funktioniert.

    ''' <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

Das integrierte Gerät If(nullable, secondChoice)kann nur zwei nullbare Optionen verarbeiten. Hier kann man beliebig Coalesceviele Parameter einstellen. Der erste Wert ungleich Null wird zurückgegeben, und der Rest der Parameter wird danach nicht ausgewertet (kurzgeschlossen, wie AndAlso/ &&und OrElse/ ||).

StingyJack
quelle
8
Weil die Sprache einen eingebauten Operator hat. Kein Grund, sich überhaupt Erweiterungsmethoden anzuschauen.
Nick
2
Ich werde die Antwort eines anderen nicht wiederholen. Ich dachte mir, dass es hilfreich sein könnte, eine alternative Lösung bereitzustellen, wenn Sie mehrere Werte mit einer einzigen Anweisung überprüfen müssen. Da es keine falsche Antwort ist, sollte es dann herabgestuft werden?
StingyJack
1
+1 für die Bereitstellung einer Implementierung unter Verwendung von Generika und die Vermeidung von Typ Casting / Boxing / Unboxing
ulty4life
4
@ Nick, sorry, aber du liegst einfach falsch. Wenn Sie mehr als zwei Koaleszenzargumente haben, wird diese durch die integrierte Funktion nicht abgeschnitten.
Toddmo
Sie könnten den obj param überspringen und den Körper sein lassen Return args.FirstOrDefault(Function(arg) arg IsNot Nothing):-)
Ulf Åkerstedt
11

Die einzige wesentliche Einschränkung der meisten dieser Lösungen besteht darin, dass sie nicht kurzschließen. Sie sind daher eigentlich nicht gleichbedeutend mit ??.

Der eingebaute IfOperator wertet nachfolgende Parameter nur aus, wenn der frühere Parameter nichts ergibt.

Die folgenden Aussagen sind äquivalent:

C #

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

VB

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

Dies funktioniert in allen Fällen, in denen dies ??funktioniert. Jede der anderen Lösungen müsste mit äußerster Vorsicht verwendet werden, da sie leicht Laufzeitfehler verursachen könnten.

user1751825
quelle
Dies funktioniert nicht in Fällen, in denen eine unbekannte Anzahl von Parametern vorhanden ist (naja, nicht ohne Roslyn oder Codedom zu verwenden, um eine Anweisung vorkompilieren zu können, die der Anzahl der Parameter zu diesem Zeitpunkt in der Ausführung entspricht).
StingyJack
@StingyJack Es ist nicht beabsichtigt. Es macht genau das was ?? Betreiber tut.
user1751825
2

Überprüfen Sie die Microsoft-Dokumentation zu If Operator (Visual Basic) hier: https://docs.microsoft.com/en-us/dotnet/visual-basic/language-reference/operators/if-operator

If( [argument1,] argument2, argument3 )

Hier einige Beispiele (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"))
FN90
quelle
1
Nett! Kommentar entfernen!
Alec