Jak sprawdzić, czy obiekt jest określonego typu

102

Przekazuję różne obiekty do podprogramu, aby uruchomić ten sam proces, ale za każdym razem używam innego obiektu. Na przykład w jednym przypadku używam ListView, aw innym przekazuję DropDownList.

Chcę sprawdzić, czy przekazywany obiekt jest DropDownList, a następnie wykonać kod, jeśli tak jest. Jak mam to zrobic?

Mój kod do tej pory nie działa:

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
źródło

Odpowiedzi:

160

W VB.NET musisz użyć GetTypemetody, aby pobrać typ wystąpienia obiektu, a GetType()operatora, aby pobrać typ innego znanego typu.

Gdy masz już dwa typy, możesz po prostu porównać je za pomocą Isoperatora.

Więc twój kod powinien być napisany w ten sposób:

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

Możesz także użyć TypeOfoperatora zamiast GetTypemetody. Zwróć uwagę, że test ten sprawdza, czy obiekt jest zgodny z danym typem, a nie, czy jest tego samego typu. To wyglądałoby tak:

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

End If

Całkowicie trywialny, nieistotny chwytak: Tradycyjnie nazwy parametrów są pisane literami camelCased (co oznacza, że ​​zawsze zaczynają się od małej litery) podczas pisania kodu .NET (VB.NET lub C #). Dzięki temu można je łatwo odróżnić na pierwszy rzut oka od klas, typów, metod itp.

Cody Gray
źródło
1
Dziękuję za odpowiedź. Próbowałem tego kodu, ale właściwie jedyną rzeczą jest to, że nie działa z operatorem „=”. Musiałem to zmienić na „Is”. Błąd, który miałem, gdy był to „=”, to „Operator” = ”nie jest zdefiniowany dla typów„ System.Type ”i„ System.Type ”."
Leah,
1
@Leah: Tak, przepraszam za to. Wygląda na to, że powinienem zacząć zwracać większą uwagę podczas pisania odpowiedzi. TypeOfjest prawdopodobnie jeszcze prostszą opcją, przynajmniej pod względem czytelności kodu; Zaktualizowałem odpowiedź, podając przykład.
Cody Gray
35
Jest między nimi ważna różnica, która doprowadziła mnie do tego postu. Sprawdzenie TypeOf zwróci True, jeśli obiekt należy do klasy, która dziedziczy po sprawdzanym typie, podczas gdy GetType zwróci True tylko wtedy, gdy jest to dokładnie ta sama klasa.
Abacus
Całkowicie banalny, nieistotny kontrapunkt: mimo że VS CodeAnalysis narzeka, nadal czuję, że nazwy argumentów są częścią publicznego interfejsu, podobnie jak PascalCase w moim kodzie.
Mark Hurd
Czy jest między nimi różnica w wydajności? - A co Select Case (Obj.GetType())z wieloma przypadkami testowymi i wieloma IF TypeOf Obj is ...?
Luke T O'Brien
3

Więcej szczegółów w związku z odpowiedzią Cody Graya. Ponieważ strawienie go zajęło mi trochę czasu, pomyślałem, że może się przydać innym.

Najpierw kilka definicji:

  1. Istnieją TypeNames, które są ciągowymi reprezentacjami typu obiektu, interfejsu itp. Na przykład Barjest TypeName w Public Class Barlub w Dim Foo as Bar. TypeNames można postrzegać jako „etykiety” używane w kodzie, aby poinformować kompilator, której definicji typu ma szukać w słowniku, w którym opisane zostaną wszystkie dostępne typy.
  2. Istnieją System.Typeobiekty, które zawierają wartość. Ta wartość wskazuje typ; tak samo, jak Stringprzyjmowałoby jakiś tekst lub Intprzyjmowałoby liczbę, z wyjątkiem tego, że przechowujemy typy zamiast tekstu lub liczb. Typeobiekty zawierają definicje typów, a także odpowiadające im TypeName.

Po drugie, teoria:

  1. Foo.GetType()zwraca Typeobiekt, który zawiera typ zmiennej Foo. Innymi słowy, mówi ci, czym Foojest instancja.
  2. GetType(Bar)zwraca Typeobiekt, który zawiera typ dla TypeName Bar.
  3. W niektórych przypadkach typ, do którego był obiekt, Castróżni się od typu, z którego został utworzony obiekt. W poniższym przykładzie MyObj jest Integerrzutowaniem na Object:

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

Więc jest MyObjtypu Objectczy typu Integer? MyObj.GetType()powie ci, że jest to plik Integer.

  1. Ale tutaj pojawia się Type Of Foo Is Barfunkcja, która pozwala upewnić się, że zmienna Foojest zgodna z TypeName Bar. Type Of MyObj Is Integeri Type Of MyObj Is Objectoba zwrócą True. W większości przypadków TypeOf wskaże, że zmienna jest zgodna z TypeName, jeśli zmienna jest tego typu lub Type, który z niej pochodzi. Więcej informacji tutaj: https://docs.microsoft.com/en-us/dotnet/visual-basic/language-reference/operators/typeof-operator#remarks

Poniższy test dość dobrze ilustruje zachowanie i użycie każdego z wymienionych słów kluczowych i właściwości.

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

EDYTOWAĆ

Możesz również użyć, Information.TypeName(Object)aby uzyskać TypeName danego obiektu. Na przykład,

Dim Foo as Bar
Dim Result as String
Result = TypeName(Foo)
Debug.Print(Result) 'Will display "Bar"
Ama
źródło