Чи є еквівалент VB.NET для C # 's' ?? ' оператор?


180

Чи існує еквівалент VB.NET для ??оператора C # ?


4
Більшість відповідей тут (включаючи прийняту відповідь) невірні та не функціонально еквівалентні ?? у всіх ситуаціях. Правильним еквівалентом є твердження if () з 2 аргументами. Однак другий аргумент може бути вкладений для досягнення таких самих результатів, як ?? з кількома аргументами.
користувач1751825

Ви маєте на увазі потрійного оператора?: Наприклад return ((значення <0)? True: false)
Zeek2

Відповіді:


155

Використовуйте 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))

3
Я думаю, що If()твердження в VB те саме, що і if...?...:в C #, а не ??оператор
Luke T O'Brien

2
@ LukeTO'Brien Це якщо ви використовуєте його з 3 аргументами. Якщо ви використовуєте його з двома аргументами, це вже більше ??(див. Іншу відповідь на це питання: stackoverflow.com/a/20686360/1474939 )
Brian J

2
Ця відповідь показує, як використовувати VB If з трьома параметрами . Це не схоже на ??оператора C # . Краща відповідь - це Код Маверика, якщо два аргументи . (Нік мав подібну відповідь роками раніше, але не містить пояснення від MSDN.)
ToolmakerSteve

1
Це дає відповідь на зовсім інше питання.
Марк Гравелл

1
Щоб зрозуміти попередні коментарі, подивіться історію редагування.
Зев Шпіц


70

Прийнята відповідь не має жодного пояснення і є просто посиланням.
Тому я подумав, що залишу відповідь, яка пояснює, як Ifпрацює оператор, взятий з MSDN:


Якщо оператор (Visual Basic)

Використовує оцінку короткого замикання для умовного повернення одного з двох значень. Оператор If може викликатися трьома аргументами або двома аргументами.

If( [argument1,] argument2, argument3 )


Якщо Оператор викликав два аргументи

Перший аргумент на 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.


Коли булевий аргумент опущено, перший аргумент повинен бути посилальним або нульовим типом. Якщо перший аргумент оцінюється як Ніщо , повертається значення другого аргументу. У всіх інших випадках повертається значення першого аргументу. Наступний приклад ілюструє, як працює ця оцінка.


В.Б.

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

Приклад того, як обробляти більше двох значень (вкладених 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)))

18

Можна використовувати метод розширення. Цей працює як 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/ ||)


8
Тому що мова має вбудований оператор. Немає причин навіть дивитися на методи розширення.
Нік

2
Я не збираюся повторювати чужу відповідь. Я подумав, що може бути непогано надати альтернативне рішення, якщо вам потрібно перевірити декілька значень за допомогою одного оператора. Оскільки його відповідь не є НЕПРАВИЛЬНОЮ відповідь, то чи варто це зволікати?
StingyJack

1
+1 за надання реалізації за допомогою дженерики та уникнення кастингу / боксу / розпакування
ulty4life

4
@ Nick, вибач, але ти просто помиляється. Якщо у вас є більше двох аргументів, що вбудовуються, вбудована функція не буде її перерізати.
toddmo

Ви можете пропустити парам obj і дозволити тілу бути Return args.FirstOrDefault(Function(arg) arg IsNot Nothing):-)
Ulf Åkerstedt

11

Одне суттєве обмеження більшості цих рішень полягає в тому, що вони не матимуть короткого замикання. Тому вони насправді не рівнозначні ??.

Вбудований Ifоператор не буде оцінювати наступні параметри, якщо попередній параметр не дорівнює.

Наступні твердження рівнозначні:

C #

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

В.Б.

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

Це буде працювати у всіх випадках, коли ??працює. Будь-яке з інших рішень доведеться використовувати з особливою обережністю, оскільки вони легко запроваджують помилки під час роботи.


Це не працює у випадках, коли є невідома кількість параметрів (ну .. не без використання roslyn або codedom для попереднього компіляції оператора, щоб відповідати кількості параметрів на той момент у виконанні).
StingyJack

@StingyJack Це не призначено. Це робить саме те, що ?? оператор робить.
користувач1751825

2

Перевірте документацію Microsoft про оператор If (Visual Basic) тут: https://docs.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
Приємно! Видалення коментаря!
Алек
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.