Comment vérifier si un objet est d'un certain type

102

Je passe différents objets à un sous-programme pour exécuter le même processus mais en utilisant un objet différent à chaque fois. Par exemple, dans un cas, j'utilise un ListView et dans un autre cas, je passe un DropDownList.

Je veux vérifier si l'objet passé est un DropDownList, puis exécuter du code si c'est le cas. Comment puis-je faire cela?

Mon code pour l'instant qui ne fonctionne pas:

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
Horrible
la source

Réponses:

160

Dans VB.NET, vous devez utiliser la GetTypeméthode pour récupérer le type d'une instance d'un objet et l' GetType()opérateur pour récupérer le type d'un autre type connu.

Une fois que vous avez les deux types, vous pouvez simplement les comparer à l'aide de l' Isopérateur.

Donc, votre code devrait en fait être écrit comme ceci:

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

Vous pouvez également utiliser l' TypeOfopérateur au lieu de la GetTypeméthode. Notez que cela teste si votre objet est compatible avec le type donné, pas qu'il est du même type. Cela ressemblerait à ceci:

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

End If

Nitpick totalement trivial et non pertinent: Traditionnellement, les noms des paramètres sont camelCased (ce qui signifie qu'ils commencent toujours par une lettre minuscule) lors de l'écriture de code .NET (VB.NET ou C #). Cela les rend faciles à distinguer en un coup d'œil des classes, types, méthodes, etc.

Cody Gray
la source
1
Merci pour votre réponse. J'ai essayé ce code mais en fait la seule chose est qu'il ne fonctionne pas avec l'opérateur '='. J'ai dû le changer en «Est». L'erreur que j'ai eue quand c'était '=' était "Operator '=' n'est pas définie pour les types 'System.Type' et 'System.Type'."
Leah le
1
@Leah: Ouais, désolé pour ça. Il semble que je devrais commencer à faire plus attention lorsque je rédige des réponses. TypeOfest probablement une option encore plus simple, au moins en termes de lisibilité du code; J'ai également mis à jour la réponse avec un exemple de cela.
Cody Gray
35
Il y a une différence importante entre les deux, c'est ce qui m'a conduit à ce poste. La vérification TypeOf renverra True si l'objet appartient à une classe qui hérite du type que vous comparez, alors que GetType ne retournera True que s'il s'agit exactement de la même classe.
Abacus
Contrepoint totalement trivial et non pertinent: même si VS CodeAnalysis se plaint, j'ai toujours le sentiment que les noms d'argument font partie de l'interface publique, tout comme PascalCase dans mon code.
Mark Hurd
Y a-t-il une différence de performance entre les deux? - Qu'en est-il Select Case (Obj.GetType())avec plusieurs cas de test Vs multiples IF TypeOf Obj is ...?
Luke T O'Brien
3

Quelques détails supplémentaires en relation avec la réponse de Cody Gray. Comme il m'a fallu un certain temps pour le digérer, j'ai pensé que cela pourrait être utile aux autres.

Tout d'abord, quelques définitions:

  1. Il existe TypeNames, qui sont des représentations sous forme de chaîne du type d'un objet, d'une interface, etc. Par exemple, Barest un TypeName dans Public Class Barou dans Dim Foo as Bar. TypeNames pourrait être vu comme des "étiquettes" utilisées dans le code pour indiquer au compilateur la définition de type à rechercher dans un dictionnaire où tous les types disponibles seraient décrits.
  2. Il y a des System.Typeobjets qui contiennent une valeur. Cette valeur indique un type; tout comme un Stringprendrait du texte ou un Intprendrait un nombre, sauf que nous stockons des types au lieu du texte ou des nombres. TypeLes objets contiennent les définitions de type, ainsi que le TypeName correspondant.

Deuxièmement, la théorie:

  1. Foo.GetType()renvoie un Typeobjet contenant le type de la variable Foo. En d'autres termes, il vous indique de quoi il Foos'agit.
  2. GetType(Bar)renvoie un Typeobjet qui contient le type du TypeName Bar.
  3. Dans certains cas, le type d'un objet Castest différent du type à partir duquel l'objet a été instancié pour la première fois. Dans l'exemple suivant, MyObj est un Integercast en un Object:

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

Alors, est MyObjde type Objectou de type Integer? MyObj.GetType()vous dira que c'est un Integer.

  1. Mais voici la Type Of Foo Is Barfonctionnalité, qui vous permet de vérifier qu'une variable Fooest compatible avec un TypeName Bar. Type Of MyObj Is Integeret Type Of MyObj Is Objectrenverra tous les deux Vrai. Dans la plupart des cas, TypeOf indiquera qu'une variable est compatible avec un TypeName si la variable est de ce Type ou d'un Type qui en dérive. Plus d'informations ici: https://docs.microsoft.com/en-us/dotnet/visual-basic/language-reference/operators/typeof-operator#remarks

Le test ci-dessous illustre assez bien le comportement et l'utilisation de chacun des mots-clés et propriétés mentionnés.

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

ÉDITER

Vous pouvez également utiliser Information.TypeName(Object)pour obtenir le TypeName d'un objet donné. Par exemple,

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