2009-01-17 6 views
1

Je suis en train de faire un simple programme orienté objet pour essayer de m'aider à maîtriser la POO. J'ai une inteface ICommand qui a la méthode Run (paramètres params object []) et j'ai différentes classes qui utilisent cette interface et implémentent leurs propres versions de run. Chaque classe a aussi une propriété de nom qui dit ce qu'est la commande et ce qu'elle fait.Polymorphisme C# - comment ne pas coder les types

Je veux avoir une interface graphique où je peux créer des commandes, qui auront probablement besoin d'une sorte de liste pour sélectionner le type de commande à créer. La question est, comment puis-je faire cette liste et le faire fonctionner sans codage en dur dans une déclaration de commutateur avec des références explicites à toutes les classes que j'ai créées.

Je suis sûr que c'est un problème très simple dont je devrais connaître la réponse, mais je ne peux pas y penser! Je suis sûr qu'il y a une réponse cependant. Oh et je m'attends à ce que certaines des réponses disent pour lire le livre de modèles de conception: bien la seule copie dans la bibliothèque est dehors pour le moment, mais je le lirai dès que possible!

Mise à jour: Je viens juste de poster une question de suivi here

Répondre

2

magasin toutes vos classes dans une liste générique de ICommand, passer outre ToString() avec le nom de votre commande et appliquer le contenu de la liste à votre liste.

var commandlist = new List<ICommand>(); 
commandList.add(new Command("Run")); 
commandList.add(new Command("Walk")); 
commandList.add(new Command("Crawl")); 
+0

Merci pour la réponse. Malheureusement, je ne comprends pas très bien ce que vous voulez dire. Qu'est-ce qu'une liste générique d'ICommand? – robintw

+0

a ajouté du code. La commande est une classe qui implémente ICommand. –

+0

Je viens de poster une question de suivi ici: http://stackoverflow.com/questions/454163/c-polymorphism-load-classes-from-dll-files – robintw

1

utiliser le modèle de stratégie (link to wikipedia), vous exécutez la méthode par Invoke ou de réflexion. Comme il y a beaucoup d'exemples, je ne vais pas énumérer ici.

0

Vous pouvez utiliser la réflexion pour trouver toutes les classes qui implémentent l'interface qui vous intéresse; Puis utilisez-le pour remplir votre liste

1

Je ne suis pas sûr que vous ayez vraiment besoin d'éviter l'invocation explicite des constructeurs. Cependant, vous pouvez faire par la réflexion - si les constructeurs de vos types ne ont pas besoin d'arguments:

var commands = new List<object>(); 
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) 
{ 
    foreach (Type type in assembly.GetTypes()) 
    { 
     if (type.GetInterface(typeof(ICommand).FullName) != null) 
     { 
      commands.Add(Activator.CreateInstance(type)); 
     } 
    } 
} 

Ce code suppose que les ensembles définissant les implémentations ICommand sont déjà chargés et ne fait aucune erreur désirée manipulation.

Une autre approche consiste à lire un fichier de configuration avec les noms des types à instancier (et peut-être même des assemblages à charger).

Cependant, dans la plupart des cas, cela n'est pas nécessaire. C'est généralement très bien d'avoir une classe CommandFactory qui appelle juste un tas de constructeurs.

Questions connexes