Bagaimana cara memeriksa apakah suatu objek adalah tipe tertentu

102

Saya mengirimkan berbagai objek ke subrutin untuk menjalankan proses yang sama tetapi menggunakan objek yang berbeda setiap saat. Misalnya, dalam satu kasus saya menggunakan ListView dan dalam kasus lain saya meneruskan DropDownList.

Saya ingin memeriksa apakah objek yang dilewatkan adalah DropDownList lalu jalankan beberapa kode jika ya. Bagaimana saya melakukan ini?

Kode saya sejauh ini yang tidak berfungsi:

Sub FillCategories(ByVal Obj As Object)
    Dim cmd As New SqlCommand("sp_Resources_Categories", Conn)
    cmd.CommandType = CommandType.StoredProcedure
    Obj.DataSource = cmd.ExecuteReader
    If Obj Is System.Web.UI.WebControls.DropDownList Then

    End If
    Obj.DataBind()
End Sub
Leah
sumber

Jawaban:

160

Di VB.NET, Anda perlu menggunakan GetTypemetode untuk mengambil tipe dari sebuah objek, dan GetType()operator untuk mengambil tipe dari tipe lain yang diketahui.

Setelah Anda memiliki kedua jenis tersebut, Anda dapat membandingkannya menggunakan Isoperator.

Jadi kode Anda seharusnya ditulis seperti ini:

Sub FillCategories(ByVal Obj As Object)
    Dim cmd As New SqlCommand("sp_Resources_Categories", Conn)
    cmd.CommandType = CommandType.StoredProcedure
    Obj.DataSource = cmd.ExecuteReader
    If Obj.GetType() Is GetType(System.Web.UI.WebControls.DropDownList) Then

    End If
    Obj.DataBind()
End Sub

Anda juga dapat menggunakan TypeOfoperator sebagai pengganti GetTypemetode. Perhatikan bahwa ini menguji jika objek Anda kompatibel dengan tipe yang diberikan, bukan tipe yang sama. Itu akan terlihat seperti ini:

If TypeOf Obj Is System.Web.UI.WebControls.DropDownList Then

End If

Benar-benar sepele, nitpick tidak relevan: Secara tradisional, nama parameter adalah camelCased (yang berarti selalu dimulai dengan huruf kecil) saat menulis kode .NET (baik VB.NET atau C #). Ini membuatnya mudah untuk dibedakan dengan sekilas pandang dari kelas, tipe, metode, dll.

Cody Grey
sumber
1
Terima kasih atas jawaban anda. Saya mencoba kode itu tetapi sebenarnya satu-satunya hal adalah kode itu tidak berfungsi dengan operator '='. Saya harus mengubahnya menjadi 'Is'. Kesalahan yang saya alami ketika '=' adalah "Operator '=' tidak ditentukan untuk tipe 'System.Type' dan 'System.Type'."
Leah
1
@ Leah: Ya, maaf tentang itu. Sepertinya saya harus mulai lebih memperhatikan saat menulis jawaban. TypeOfmungkin merupakan opsi yang lebih sederhana, setidaknya dalam hal keterbacaan kode; Saya telah memperbarui jawabannya dengan contoh itu juga.
Cody Gray
35
Ada perbedaan penting antara keduanya, itulah yang membawa saya ke posting ini. Pemeriksaan TypeOf akan mengembalikan True jika objek dari kelas yang mewarisi dari jenis yang Anda periksa, sedangkan GetType hanya akan mengembalikan True jika itu adalah kelas yang persis sama.
Abacus
Benar-benar sepele, tandingan yang tidak relevan: Meskipun VS CodeAnalysis mengeluh, saya masih merasa nama argumen adalah bagian dari antarmuka publik dan begitu juga PascalCase dalam kode saya.
Mark Hurd
Apakah ada perbedaan performa antara keduanya? - Bagaimana Select Case (Obj.GetType())dengan beberapa kasus uji Vs multipel IF TypeOf Obj is ...?
Luke T O'Brien
3

Beberapa detail lebih lanjut terkait dengan tanggapan dari Cody Grey. Karena saya butuh waktu untuk mencernanya, saya pikir itu mungkin berguna bagi orang lain.

Pertama, beberapa definisi:

  1. Ada TypeNames, yang merupakan representasi string dari jenis objek, antarmuka, dll. Misalnya, Baradalah TypeName dalam Public Class Bar, atau dalam Dim Foo as Bar. TypeNames bisa dilihat sebagai "label" yang digunakan dalam kode untuk memberi tahu kompiler definisi tipe mana yang harus dicari dalam kamus di mana semua tipe yang tersedia akan dijelaskan.
  2. Ada System.Typeobjek yang mengandung nilai. Nilai ini menunjukkan tipe; sama seperti a Stringakan mengambil beberapa teks atau Intakan mengambil angka, kecuali kita menyimpan tipe, bukan teks atau angka. Typeobjek berisi definisi tipe, serta TypeName yang sesuai.

Kedua, teori:

  1. Foo.GetType()mengembalikan Typeobjek yang berisi tipe untuk variabel Foo. Dengan kata lain, ini memberi tahu Anda apa Fooitu instance.
  2. GetType(Bar)mengembalikan Typeobjek yang berisi tipe untuk TypeName Bar.
  3. Dalam beberapa contoh, tipe objek yang dikunjungi Castberbeda dari tipe objek pertama kali dibuat. Dalam contoh berikut, MyObj di- Integercast menjadi Object:

    Dim MyVal As Integer = 42 Dim MyObj As Object = CType(MyVal, Object)

Jadi, apakah MyObjtipe Objectatau tipenya Integer? MyObj.GetType()akan memberi tahu Anda bahwa ini adalah Integer.

  1. Tapi inilah Type Of Foo Is Barfitur, yang memungkinkan Anda untuk memastikan variabel Fookompatibel dengan TypeName Bar. Type Of MyObj Is Integerdan Type Of MyObj Is Objectkeduanya akan mengembalikan True. Untuk kebanyakan kasus, TypeOf akan menunjukkan bahwa variabel kompatibel dengan TypeName jika variabel tersebut adalah Jenis atau Jenis yang berasal darinya. Info lebih lanjut di sini: https://docs.microsoft.com/en-us/dotnet/visual-basic/language-reference/operators/typeof-operator#remarks

Pengujian di bawah ini menggambarkan dengan baik perilaku dan penggunaan setiap kata kunci dan properti yang disebutkan.

Public Sub TestMethod1()

    Dim MyValInt As Integer = 42
    Dim MyValDble As Double = CType(MyValInt, Double)
    Dim MyObj As Object = CType(MyValDble, Object)

    Debug.Print(MyValInt.GetType.ToString) 'Returns System.Int32
    Debug.Print(MyValDble.GetType.ToString) 'Returns System.Double
    Debug.Print(MyObj.GetType.ToString) 'Returns System.Double

    Debug.Print(MyValInt.GetType.GetType.ToString) 'Returns System.RuntimeType
    Debug.Print(MyValDble.GetType.GetType.ToString) 'Returns System.RuntimeType
    Debug.Print(MyObj.GetType.GetType.ToString) 'Returns System.RuntimeType

    Debug.Print(GetType(Integer).GetType.ToString) 'Returns System.RuntimeType
    Debug.Print(GetType(Double).GetType.ToString) 'Returns System.RuntimeType
    Debug.Print(GetType(Object).GetType.ToString) 'Returns System.RuntimeType

    Debug.Print(MyValInt.GetType = GetType(Integer)) '# Returns True
    Debug.Print(MyValInt.GetType = GetType(Double)) 'Returns False
    Debug.Print(MyValInt.GetType = GetType(Object)) 'Returns False

    Debug.Print(MyValDble.GetType = GetType(Integer)) 'Returns False
    Debug.Print(MyValDble.GetType = GetType(Double)) '# Returns True
    Debug.Print(MyValDble.GetType = GetType(Object)) 'Returns False

    Debug.Print(MyObj.GetType = GetType(Integer)) 'Returns False
    Debug.Print(MyObj.GetType = GetType(Double)) '# Returns True
    Debug.Print(MyObj.GetType = GetType(Object)) 'Returns False

    Debug.Print(TypeOf MyObj Is Integer) 'Returns False
    Debug.Print(TypeOf MyObj Is Double) '# Returns True
    Debug.Print(TypeOf MyObj Is Object) '# Returns True


End Sub

EDIT

Anda juga bisa menggunakan Information.TypeName(Object)untuk mendapatkan TypeName dari objek tertentu. Sebagai contoh,

Dim Foo as Bar
Dim Result as String
Result = TypeName(Foo)
Debug.Print(Result) 'Will display "Bar"
Ama
sumber