2010-07-15 15 views
4

Je suis en train de faire une méthode FindControl générique et je reçois l'erreur suivante:Impossible de convertir le type « System.Windows.Forms.Control » « T »

ne peut pas convertir type « System.Windows.Forms. contrôle » 'T'

code:

public T Control<T>(String id) 
{ 
    foreach (Control ctrl in MainForm.Controls.Find(id, true)) 
    { 
    return (T)ctrl; // Form Controls have unique names, so no more iterations needed 
    } 

    throw new Exception("Control not found!"); 
} 
+0

Quelle valeur passez-vous pour 'T' lorsque vous appelez cette méthode? – Jamiec

+0

@Jamiec: cela n'a pas vraiment d'importance pour le compilateur, à moins que vous * disiez * que T sera toujours un 'Control' sur lequel il ne peut pas s'appuyer, que vous passiez toujours ou non a 'Control' ... –

+0

(Hors-sujet :) Pensez à lancer une exception d'un type plus spécifique, peut-être' KeyNotFoundException' (à partir de l'espace de noms 'System.Collections.Generic'). – stakx

Répondre

8

essayer cette

public T Control<T>(String id) where T : Control 
{ 
    foreach (Control ctrl in MainForm.Controls.Find(id, true)) 
    { 
    return (T)ctrl; // Form Controls have unique names, so no more iterations needed 
    } 

    throw new Exception("Control not found!"); 
} 
+0

Comme vous avez répondu en premier, vous obtenez la réponse! –

0

Comment appelez-vous cette méthode, avez-vous un exemple?

Aussi, je voudrais ajouter une contrainte à votre méthode:

public T Control<T>(string id) where T : System.Windows.Forms.Control 
{ 
    // 
} 
1

Comme T est sans contrainte, vous pouvez passer quoi que ce soit pour le paramètre de type. Vous devez ajouter une contrainte "where" à la signature de votre méthode:

 
public T Control<T>(string id) where T : Control 
{ 
    ... 
} 
 
+0

Code invalide .... – leppie

+0

Vous avez oublié d'ajouter la définition générique à la méthode: Contrôle (chaîne ....) –

+0

Oups, vous avez en effet raison. Corrigée. –

3

Vous pouvez toujours modifier les règles et effectuer une double conversion. Par exemple:

public T Control<T>(String id) 
{ 
    foreach (Control ctrl in MainForm.Controls.Find(id, true)) 
    { 
    return (T)(object)ctrl; 
    } 

    throw new Exception("Control not found!"); 
} 
+1

vous pourriez! mais c'est une idée terrible, considérant qu'il y a une bonne façon de le faire –

+0

C'est le seul moyen de traiter les types de valeurs ou les primitives. Mais je suis d'accord, dans ce cas, le «bon» serait préférable. – leppie

-1

Changer votre signature de la méthode à ceci:

public T Control<T>(String id) where T : Control 

Déclarant que tous les T de sont en fait de type Control. Cela va contraindre T et le compilateur sait que vous pouvez le renvoyer comme T.

0

Alors que d'autres personnes ont déjà indiqué correctement quel est le problème, je veux juste souligner que cela serait tout à fait approprié pour une méthode d'extension. Ne pas upvote cela, c'est en fait un commentaire, je posterai tout comme une réponse pour que je puisse gagner la capacité d'écrire plus et formater mon code mieux;)

public static class Extensions 
{ 
    public static T FindControl<T>(this Control parent, string id) where T : Control 
    { 
     return item.FindControl(id) as T; 
    } 
} 

Alors que vous pouvez invoquer il comme ainsi:

Label myLabel = MainForm.Controls.FindControl<Label>("myLabelID"); 
Questions connexes