Existe-t-il un équivalent VB.NET pour C # '??' opérateur?

182

Existe-t-il un équivalent VB.NET pour l' ??opérateur C # ?

Nathan Koop
la source
4
La plupart des réponses ici (y compris la réponse acceptée) ne sont pas correctes et ne sont pas fonctionnellement équivalentes à ?? dans toutes les situations. L'équivalent correct est l'instruction if () avec 2 arguments. Le deuxième argument peut cependant être imbriqué pour obtenir exactement les mêmes résultats que ?? avec plusieurs arguments.
user1751825
Voulez-vous dire l'opérateur ternaire?:
Eg

Réponses:

158

Utilisez l' If()opérateur avec deux arguments ( documentation 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))
Firas Assaad
la source
3
Je pense que la If()déclaration en VB est la même que celle if...?...:en C #, pas l' ??opérateur
Luke T O'Brien
3
@ LukeTO'Brien C'est si vous l'utilisez avec 3 arguments. Si vous l'utilisez avec 2 arguments, c'est plus que ??(voir une autre réponse à cette question: stackoverflow.com/a/20686360/1474939 )
Brian J
2
Cette réponse montre comment utiliser VB If avec trois paramètres . Ce n'est pas similaire à l' ??opérateur de C # . La meilleure réponse est le If de Code Maverick avec deux arguments . (Nick avait une réponse similaire, des années plus tôt, mais n'inclut pas l'explication de MSDN.)
ToolmakerSteve
1
Cela répond à une question complètement différente.
Marc Gravell
2
Pour comprendre les commentaires précédents, consultez l'historique des modifications.
Zev Spitz
70

La réponse acceptée n'a aucune explication et n'est qu'un lien.
Par conséquent, j'ai pensé laisser une réponse expliquant le fonctionnement de l' Ifopérateur à partir de MSDN:


Si, opérateur (Visual Basic)

Utilise l'évaluation des courts-circuits pour renvoyer conditionnellement l'une des deux valeurs. L' opérateur If peut être appelé avec trois arguments ou avec deux arguments.

If( [argument1,] argument2, argument3 )


Si l'opérateur est appelé avec deux arguments

Le premier argument de If peut être omis. Cela permet à l'opérateur d'être appelé en utilisant seulement deux arguments. La liste suivante s'applique uniquement lorsque l' opérateur If est appelé avec deux arguments.


les pièces

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.


Lorsque l' argument booléen est omis, le premier argument doit être une référence ou un type Nullable. Si le premier argument a la valeur Nothing , la valeur du deuxième argument est renvoyée. Dans tous les autres cas, la valeur du premier argument est renvoyée. L'exemple suivant illustre le fonctionnement de cette évaluation.


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

Exemple de gestion de plus de deux valeurs (imbriquées 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)))
Code Maverick
la source
19

Vous pouvez utiliser une méthode d'extension. Celui-ci fonctionne comme SQL COALESCEet est probablement excessif pour ce que vous essayez de tester, mais cela fonctionne.

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

L'intégré If(nullable, secondChoice)ne peut gérer que deux choix Nullable. Ici, on peut Coalesceautant de paramètres que souhaité. Le premier non nul sera retourné, et le reste des paramètres ne sera pas évalué après cela (court-circuité, comme AndAlso/ &&et OrElse/ ||)

StingyJack
la source
9
Parce que le langage a un opérateur intégré. Aucune raison de regarder même les méthodes d'extension.
Nick
2
Je ne vais pas répéter la réponse de quelqu'un d'autre. J'ai pensé qu'il serait peut-être bien de fournir une solution alternative si vous devez vérifier plusieurs valeurs avec une seule instruction. Puisque ce n'est pas une mauvaise réponse, alors devrait-il être déclassé?
StingyJack
1
+1 pour fournir une implémentation utilisant des génériques et éviter le type casting / boxing / unboxing
ulty4life
4
@Nick, désolé, mais vous avez tout simplement tort. Si vous avez plus de deux arguments de fusion, la fonction intégrée ne le coupera pas.
toddmo
Vous pouvez ignorer le paramètre obj et laisser le corps être Return args.FirstOrDefault(Function(arg) arg IsNot Nothing):-)
Ulf Åkerstedt
12

La seule limitation importante de la plupart de ces solutions est qu'elles ne court-circuitent pas. Ils ne sont donc pas réellement équivalents à ??.

L' Ifopérateur intégré n'évalue pas les paramètres suivants à moins que le paramètre précédent n'évalue à rien.

Les affirmations suivantes sont équivalentes:

C #

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

VB

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

Cela fonctionnera dans tous les cas où cela ??fonctionne. Toutes les autres solutions devraient être utilisées avec une extrême prudence, car elles pourraient facilement introduire des bogues d'exécution.

user1751825
la source
Cela ne fonctionne pas dans les cas où il y a un nombre inconnu de paramètres (enfin ... pas sans utiliser roslyn ou codedom pour précompiler une instruction afin qu'elle corresponde au nombre de paramètres à ce moment de l'exécution).
StingyJack
@StingyJack Ce n'est pas prévu. Il fait exactement ce que le ?? l'opérateur le fait.
user1751825
2

Consultez la documentation Microsoft sur If Operator (Visual Basic) ici: https://docs.microsoft.com/en-us/dotnet/visual-basic/language-reference/operators/if-operator

If( [argument1,] argument2, argument3 )

Voici quelques exemples (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
la source
1
Agréable! Suppression du commentaire!
cela