Esiste un equivalente VB.NET per C # 's' ?? ' operatore?


180

Esiste un equivalente VB.NET per l' ??operatore di C # ?


4
La maggior parte delle risposte qui (compresa la risposta accettata) non sono corrette e non sono funzionalmente equivalenti a ?? in tutte le situazioni. L'equivalente corretto è l'istruzione if () con 2 argomenti. Tuttavia, il secondo argomento può essere nidificato per ottenere esattamente gli stessi risultati di ?? con più argomenti.
user1751825,

Intendi l'operatore ternario?: Ad es. Return ((valore <0)? True: false)
Zeek2

Risposte:


155

Utilizzare l' If()operatore con due argomenti ( documentazione di 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))

3
Penso che l' If()affermazione in VB sia la stessa di if...?...:in C #, non ??dell'operatore
Luke T O'Brien,

2
@ LukeTO'Brien Questo è se lo usi con 3 argomenti. Se lo usi con 2 argomenti, è molto di più ??(vedi un'altra risposta a questa domanda: stackoverflow.com/a/20686360/1474939 )
Brian J

2
Questa risposta mostra come usare VB If con tre parametri . Questo non è simile all'operatore di C # ??. La risposta migliore è If di Code Maverick con due argomenti . (Nick aveva una risposta simile, anni prima, ma non include la spiegazione di MSDN.)
ToolmakerSteve

1
Questo risponde a una domanda completamente diversa.
Marc Gravell

1
Per comprendere i commenti precedenti, guarda la cronologia delle modifiche.
Zev Spitz,


70

La risposta accettata non ha alcuna spiegazione ed è semplicemente un link.
Pertanto, ho pensato di lasciare una risposta che spiega come funziona l' Ifoperatore preso da MSDN:


Operatore If (Visual Basic)

Utilizza la valutazione di corto circuito per restituire condizionalmente uno dei due valori. L' operatore If può essere chiamato con tre argomenti o con due argomenti.

If( [argument1,] argument2, argument3 )


Se l'operatore ha chiamato con due argomenti

Il primo argomento di If può essere omesso. Ciò consente di chiamare l'operatore utilizzando solo due argomenti. L'elenco seguente si applica solo quando l' operatore If viene chiamato con due argomenti.


Parti

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.


Quando l' argomento booleano viene omesso, il primo argomento deve essere un tipo di riferimento o nullable. Se il primo argomento non restituisce nulla , viene restituito il valore del secondo argomento. In tutti gli altri casi, viene restituito il valore del primo argomento. L'esempio seguente mostra come funziona questa valutazione.


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

Un esempio di come gestire più di due valori ( ifs nidificati ):

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

18

È possibile utilizzare un metodo di estensione. Questo funziona come SQL COALESCEed è probabilmente eccessivo per quello che stai cercando di testare, ma funziona.

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

Il built-in If(nullable, secondChoice)può gestire solo due scelte annullabili. Qui, si possono Coalescequanti parametri si desidera. Verrà restituito il primo non null e il resto dei parametri non verrà valutato successivamente (cortocircuito, come AndAlso/ &&e OrElse/ ||)


8
Perché la lingua ha un operatore integrato. Nessun motivo per guardare anche ai metodi di estensione.
Nick,

2
Non ripeterò la risposta di qualcun altro. Ho pensato che potrebbe essere utile fornire una soluzione alternativa se è necessario controllare più valori con una singola istruzione. Dal momento che non è una risposta ERRATA, allora dovrebbe essere votato verso il basso?
StingyJack,

1
+1 per fornire un'implementazione usando i generici ed evitare il casting / boxing / unboxing di tipo
ulty4life

4
@Nick, scusa, ma ti sbagli di grosso. Se hai più di due argomenti di coalescenza, la funzione integrata non lo taglierà.
toddmo,

Potresti saltare l'obj param e lasciare che il corpo sia Return args.FirstOrDefault(Function(arg) arg IsNot Nothing):-)
Ulf Åkerstedt,

11

L'unico limite significativo della maggior parte di queste soluzioni è che non cortocircuiteranno. Pertanto non sono effettivamente equivalenti a ??.

L' Ifoperatore integrato non valuterà i parametri successivi a meno che il parametro precedente non valuti nulla.

Le seguenti dichiarazioni sono equivalenti:

C #

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

VB

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

Questo funzionerà in tutti i casi in cui ??funziona. Tutte le altre soluzioni dovrebbero essere utilizzate con estrema cautela, in quanto potrebbero facilmente introdurre bug di runtime.


Questo non funziona nei casi in cui esiste un numero sconosciuto di parametri (beh ... non senza usare roslyn o codedom per precompilare un'istruzione per abbinare il numero di parametri in quel momento nell'esecuzione).
StingyJack,

@StingyJack Non è previsto. Fa esattamente quello che ?? l'operatore lo fa.
user1751825

2

Consulta la documentazione Microsoft su If Operator (Visual Basic) qui: https://docs.microsoft.com/en-us/dotnet/visual-basic/language-reference/operators/if-operator

If( [argument1,] argument2, argument3 )

Ecco alcuni esempi (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
Bello! Rimozione del commento!
Alec,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.