2010-04-16 4 views
3

Je le code suivant:Comment savoir si un objet est de <type> ou un decendant de <type>

foreach (var control in this.Controls) 
{ 

} 

Je veux faire quelque chose comme control.Hide() là-dedans. Mais les éléments de la collection this.Controls ne sont pas de type Control (ils sont Object).

Je n'arrive pas à me souvenir de la façon sécuritaire de lancer cette fonction pour appeler hide si elle est vraiment de type Control et ne rien faire d'autre. (Je suis un programmeur delphi transplanté et je continue à penser quelque chose comme control is Control.)

Répondre

5

est ici un cas où vous ne souhaitez pas utiliser var.

foreach (Control control in this.Controls) 
{ 
    control.Hide(); 
} 

fait exactement ce que vous voulez.

Testez-le si vous ne croyez pas.

Pour d'autres scénarios où vous pourriez éventuellement avoir une collection mixte, vous pourriez faire quelque chose comme

foreach (var foo in listOfObjects.OfType<Foo>()) 
{ 

} 
+0

Je n'ai pas fait cela parce que resharper pensait que la seule autre option pour cette collection était 'Object'.J'ai supposé (comme je l'ai indiqué dans ma question) que les valeurs retournées par la collection étaient de type 'Object' et pourraient être de type différent de classes. – Vaccano

+1

Dans ce cas, R # est faux et Anthong Pegram a raison. Tous les objets de la collection Controls seront de type Control, il est donc sûr de déclarer la variable d'itération comme 'Control'. Les autres solutions compliquent à l'extrême quelque chose de vraiment simple. – EMP

+1

La ControlCollection est pré-générique en C# et n'est donc pas fortement typée, c'est pourquoi l'inférence de type sur var tire l'objet au lieu de Control. Cependant, vous devriez être sûr de dire Contrôle de contrôle plutôt que contrôle de var puisque la collection ne contient réellement que des contrôles. Tout comme si vous aviez un ArrayList contenant uniquement des ints, vous pourriez dire (int i dans arrayList) même si techniquement il stocke des éléments comme des objets. –

0

Il y a plusieurs façons de le faire:

if (control is Control) 
    ((Control)control).Hide(); 

ou

if (control is Control) 
    (control as Control).Hide(); 

ou si vous voulez juste itérer au cours des contrôles,

foreach(var control in this.Controls.Cast<Control>()) 
    control.Hide(); 
+0

-1: Pour chacun de vos trois exemples, il existe une meilleure façon de procéder. Les deux premiers devraient être un as suivi d'une vérification nulle. Le dernier devrait utiliser 'OfType' au lieu de' Cast', ou utiliser 'foreach (Control control dans this.Controls)', selon le comportement prévu. –

1

C'est exactement ça.

foreach (var control in this.Controls) 
{ 
    if(control is Control) 
    { 
     ((Control)control).Hide(); 
    } 
} 
+1

-1: Pour C# 3, c'est * tellement * beaucoup plus propre à utiliser 'var control dans this.Controls.OfType ()' –

+0

Bon à savoir, merci. –

1
Control c = control as Control; 
if (c != null) 
    c.Hide(); 

ou

if (control is Control) 
    ((Control)control).Hide(); 
+0

Vous les avez dans le mauvais ordre - 'as' est préférable à' is'. –

+0

Modifié l'ordre, pour refléter le fait que 'comme' est préférable à 'est'. – MatthewKing

1

Ou, comme alternative, vous pouvez également faire

foreach(var control in this.Controls.OfType<Control>()) 
{ 
    control.Hide(); 
} 
+0

(il n'est pas clair si l'OP * sait * que tous les éléments sont 'Control's - sinon,' OfType' serait mieux que 'Cast') –

+0

Ouais bon point, modifié. –

1

Toutes les autres réponses (confirmant votre intuition) probablement raison.

J'ai rencontré une situation où Type.IsAssignableFrom correspondait à ce dont j'avais besoin quand is ne l'a pas fait. (Malheureusement, je ne me souviens pas maintenant de la situation.)

Questions connexes