Apakah ada VB.NET yang setara untuk C # 's' ?? ' operator?

180

Apakah ada VB.NET yang setara untuk ??operator C # ?

Nathan Koop
sumber
4
Sebagian besar jawaban di sini (termasuk jawaban yang diterima) tidak benar, dan tidak secara fungsional setara dengan ?? dalam semua situasi. Persamaan yang benar adalah pernyataan if () dengan 2 argumen. Namun argumen kedua dapat disarangkan untuk mencapai hasil yang sama persis seperti ?? dengan banyak argumen.
user1751825
Apakah maksud Anda operator ternary
?:

Jawaban:

155

Gunakan If()operator dengan dua argumen ( dokumentasi 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
sumber
3
Saya pikir If()pernyataan dalam VB sama dengan if...?...:di C #, bukan ??operator
Luke T O'Brien
2
@ LukeTO'Brien Itu jika Anda menggunakannya dengan 3 argumen. Jika Anda menggunakannya dengan 2 argumen, lebih dari itu ??(lihat jawaban lain untuk pertanyaan ini: stackoverflow.com/a/20686360/1474939 )
Brian J
2
Jawaban ini menunjukkan cara menggunakan VB If dengan tiga parameter . Itu tidak mirip dengan ??operator C # . Jawaban yang lebih baik adalah Kode Maverick Jika dengan dua argumen . (Nick memiliki jawaban yang sama, bertahun-tahun sebelumnya, tetapi tidak termasuk penjelasan dari MSDN.)
ToolmakerSteve
1
Ini menjawab pertanyaan yang sama sekali berbeda.
Marc Gravell
1
Untuk memahami komentar sebelumnya, lihat pada riwayat edit.
Zev Spitz
70

Jawaban yang diterima tidak memiliki penjelasan apa pun dan hanya berupa tautan.
Oleh karena itu, saya pikir saya akan meninggalkan jawaban yang menjelaskan cara kerja Ifoperator diambil dari MSDN:


Jika Operator (Visual Basic)

Menggunakan evaluasi hubung singkat untuk mengembalikan satu dari dua nilai secara kondisional. The Jika operator dapat disebut dengan tiga argumen atau dengan dua argumen.

If( [argument1,] argument2, argument3 )


Jika Operator Dipanggil dengan Dua Argumen

Argumen pertama ke Jika bisa dihilangkan. Ini memungkinkan operator dipanggil dengan hanya menggunakan dua argumen. Daftar berikut ini hanya berlaku ketika operator If dipanggil dengan dua argumen.


Bagian

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.


Ketika argumen Boolean dihilangkan, argumen pertama harus berupa tipe referensi atau nullable. Jika argumen pertama mengevaluasi ke Nothing , nilai argumen kedua dikembalikan. Dalam semua kasus lain, nilai argumen pertama dikembalikan. Contoh berikut menggambarkan cara kerja evaluasi ini.


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

Contoh cara menangani lebih dari dua nilai (bersarang 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
sumber
18

Anda dapat menggunakan metode ekstensi. Yang ini bekerja seperti SQL COALESCEdan mungkin berlebihan untuk apa yang Anda coba untuk menguji, tetapi berhasil.

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

Built-in If(nullable, secondChoice)hanya dapat menangani dua pilihan yang dapat dibatalkan. Di sini, satu Coalesceparameter dapat sebanyak yang diinginkan. Yang bukan-nol pertama akan dikembalikan, dan parameter lainnya tidak dievaluasi setelah itu (dihubung pendek, seperti AndAlso/ &&dan OrElse/ ||)

Pelit
sumber
8
Karena bahasa memiliki operator bawaan. Tidak ada alasan untuk melihat metode ekstensi.
Nick
2
Saya tidak akan mengulangi jawaban orang lain. Saya pikir mungkin baik untuk memberikan solusi alternatif jika Anda perlu memeriksa beberapa nilai dengan satu pernyataan. Karena itu bukan jawaban yang SALAH, maka haruskah itu diturunkan?
StingyJack
1
+1 untuk memberikan implementasi menggunakan obat generik dan menghindari jenis casting / tinju / unboxing
ulty4life
4
@Nick, maaf, tapi Anda salah besar. Jika Anda memiliki lebih dari dua argumen gabungan, fungsi bawaan tidak akan memotongnya.
toddmo
Anda bisa melewatkan param obj dan membiarkan tubuhnya Return args.FirstOrDefault(Function(arg) arg IsNot Nothing):-)
Ulf Åkerstedt
11

Satu batasan signifikan dari sebagian besar solusi ini adalah mereka tidak akan mengalami hubungan pendek. Karena itu mereka sebenarnya tidak setara dengan ??.

Built-in IfOperator tidak akan mengevaluasi parameter berikutnya kecuali mengevaluasi parameter sebelumnya untuk apa-apa.

Pernyataan berikut ini setara:

C #

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

VB

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

Ini akan berfungsi dalam semua kasus di mana ??bekerja. Salah satu solusi lain harus digunakan dengan sangat hati-hati, karena mereka dapat dengan mudah memperkenalkan bug run-time.

pengguna1751825
sumber
Ini tidak berfungsi dalam kasus di mana ada sejumlah parameter yang tidak diketahui (yah .. bukan tanpa menggunakan roslyn atau codedom untuk mengkompilasi pernyataan agar sesuai dengan jumlah parameter pada saat itu dalam eksekusi).
StingyJack
@ StingyJack Ini tidak dimaksudkan untuk. Itu tidak persis apa ?? operator tidak.
user1751825
2

Periksa dokumentasi Microsoft tentang If Operator (Visual Basic) di sini: https://docs.microsoft.com/en-us/dotnet/visual-basic/language-reference/operators/if-operator

If( [argument1,] argument2, argument3 )

Berikut adalah beberapa contoh (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
sumber
1
Bagus! Menghapus komentar!
Alec