2009-08-19 10 views
36

Je ne suis pas sûr si ce C# valide, mais j'espère que vous avez l'idée. :)Sélectionnez Case sur le type d'un objet dans VB.NET

switch (msg.GetType()) { 
    case ClassA: 
     // blah 
    case ClassB: 
     // blah 2 
    case ClassC: 
     // blah 3 
} 

Comment puis-je allumer mais en utilisant Select Case de VB.NET type d'un objet?

Je suis conscient que certains pourraient suggérer d'utiliser polymorphism, mais j'utilise une hiérarchie de petites classes de message, ce qui ne fonctionnerait vraiment pas dans mon cas.

Répondre

69

Avec VB 2010, pour des projets ciblant le framework .NET 4 et versions ultérieures, vous pouvez le faire:

Select Case msg.GetType() 
    Case GetType(ClassA) 
End Select 

Dans les versions VB précédentes, il ne fonctionne pas parce que vous ne pouviez pas comparer deux types avec égalité. Vous devrez vérifier s'ils pointent vers la même référence en utilisant le mot-clé Is. Il n'est pas possible de le faire dans un cas de sélection, sauf si vous utilisez une propriété du type Nom ou Nom complet pour la comparaison, comme suggéré par Michael. Vous pouvez utiliser une combinaison de Si et ElseIf si:

Dim type = msg.GetType() 
If type Is GetType(ClassA) 
    ... 
ElseIf type Is GetType(ClassB) 
    ... 
... 
End If 
+0

Je vais juste utiliser 'If' /' ElseIf's. Kinda craint qu'il n'y ait pas de moyen de commuter. – mcjabberz

+1

Pour être précis, cela ne fonctionnera que dans .Net Framework 4 et versions ultérieures. [Type.Equality Operator] (http://msdn.microsoft.com/fr-fr/library/system.type.op_equality.aspx) – Jon

+2

Vous pouvez prendre cela avec un grain de sel et faire vos propres tests de perf: Ma propre Le simple test de performance de 'If/ElseIf' vs' Select Case' a prouvé que l'option 'If/ElseIf' était plus rapide à chaque fois. Le 'Select Case' a pris environ 4 fois plus de temps. Je vais m'en tenir à 'If/ElseIf' pour le moment. – Airn5475

20

Eh bien, si vous insistez sur l'utilisation de Select Case, vous pouvez toujours aller avec:

Select Case True 
    Case TypeOf msg Is ClassA 
     ' do something ' 
    Case TypeOf msg Is ClassB 
     ' do something else ' 
    Case Else 
     ' and so on ' 
End Select 

Mais j'imagine la plupart des gens aiment éviter ce genre de chose. Si/ElseIf serait probablement plus clair.

+10

S'il vous plaît éviter ce genre de chose! :) – MarkJ

+2

Je suis ambivalent sur celui-ci si le bloc est court. Quel serait l'argument contre cette section de code? –

+6

En fait, cela ne semble pas mal du tout, surtout quand vous avez plusieurs cas (fall-through) - cela semblerait mieux que MILES que si les déclarations ... –

1

Ce:

Dim a As Object = New TextBox 

Select Case True 
    Case TypeOf a Is TextBox 
     MsgBox("aaa") 

    Case TypeOf a Is ComboBox 

    Case TypeOf a Is ListBox 

End Select 
6

C'est un moyen de gérer les événements cliquez sur Button1 et Bouton2 dans le même sous (j'ai commencé en tant que programmeur VB6, donc c'est un bon substitut pour le traitement VB6 des tableaux de commande)

Private Sub Button1_Click(ByVal sender As System.Object, _ 
ByVal e As System.EventArgs) Handles Button1.Click, Button2.Click 
       Select Case True 
        Case sender Is Me.Button1 
         ' Do Button1 stuff ' 
        Case sender Is Me.Button2 
         ' Do Button2 stuff ' 
       End Select 
      End Sub 
+0

assez élégant! et il fonctionne! – KnF

4

Je ne jamais select case true, mais vous pouvez le faire:

Select Case msg.GetType.Name 
    Case GetType(ClassA).Name 
     ... 
    Case GetType(ClassB).Name 
     ... 
    Case Else 
     ... 
End Select 

Quelle st h est légèrement plus propre que ça:

If msg.GetType Is GetType(ClassA) Then 
    ... 
ElseIf msg.GetType Is GetType(ClassB) Then 
    ... 
Else 
    ... 
End If 
+0

C'est peut-être plus clair, mais c'est aussi environ cent fois moins rapide. Mais il ferait le travail s'il veut vraiment le faire de cette façon. – Bernesto

+0

@Bernesto - Une centaine de fois plus lent que quoi? Cette réponse est la même que la réponse acceptée (je n'ai pas 2010 pour tester la performance de type égalité). Je ne crois pas que ça devrait être un -1? –

+0

Si Type.Name n'est pas un nom de type complet, il peut y avoir un conflit si deux classes ont le même nom mais sont dans des espaces de noms différents. –