2010-05-05 7 views
0

J'ai eu du mal à trouver un bon titre pour cette question, donc les suggestions sont les bienvenues.Meilleur moyen pour obtenir des objets avec la classe de base commune

Disons que nous avons une classe de base abstraite ActionBase qui ressemble à ceci:

public abstract class ActionBase 
{ 
    public abstract string Name { get; } 
    public abstract string Description { get; } 

    // rest of declaration follows 
} 

Et nous avons un tas de différentes actions définies, comme un MoveFileAction, WriteToRegistryAction, etc. Ces actions se joint aux travailleurs objets:

public class Worker 
{ 
    private IList<ActionBase> _actions = new List<ActionBase>(); 
    public IList<ActionBase> Actions { get { return _actions; } } 

    // worker stuff ... 
} 

Jusqu'ici, assez simple. Maintenant, j'aimerais avoir une interface utilisateur pour configurer les travailleurs, assigner des actions, définir des propriétés, etc. Dans cette interface, je souhaite présenter une liste de toutes les actions disponibles, ainsi que leurs propriétés, et pour cela, je voudrais d'abord rassembler tous les noms et descriptions des actions disponibles (plus le type) dans une collection des éléments suivants Type d'article:

public class ActionDescriptor 
{ 
    public string Name { get; } 
    public string Description { get; } 
    poblic Type Type { get; } 
} 

Certes, je peux utiliser la réflexion pour faire cela, mais y at-il un meilleur moyen? Avoir le nom et la description être des propriétés d'instance de ActionBase (par opposition à la statique sur les classes dérivées) sent un peu, mais il n'y a pas de statique abstraite dans C#.

Merci!

+0

Il n'y a pas 'static static' car il n'y a pas de concept d'héritage statique. –

+0

Je ne suis pas en train de plaider en faveur d'un «résumé statique», en notant simplement que le mot-clé «abstract» aide à faire respecter un contrat. –

+0

Je devrais peut-être élaborer. Je ne suis pas en train de défendre l'abstrait statique et je comprends pourquoi nous ne l'avons pas en C#. Ce que je veux dire, c'est que les propriétés Nom et Description n'ont pas vraiment de sens sur une instance d'objet, mais je veux forcer chaque implémentation à avoir un nom et une description et il n'y a pas moyen d'appliquer ce contrat avec Propriété 'static'. –

Répondre

2

Ce dont vous parlez, c'est de créer des métadonnées pour vos classes d'actions concrètes pour les décrire. Pour le cas simple de nom et la description, je recommande le DisplayName et description des attributs comme ceci:

[DisplayName("MyAction Name")] 
[Description("My description goes here")] 
public class MyAction : ActionBase 
{ 
    //Declaration goes here 
} 

Ces attributs sont définis dans System.ComponentModel.

+0

Merci Dan. Avec cette approche, utiliseriez-vous toujours la réflexion pour rassembler la liste? –

+0

Oui, vous devez Reflect pour localiser les dérivés ActionBase, puis utiliser Attribute.GetCustomAttribute pour récupérer les attributs. –

+0

Quelles alternatives à la réflexion pour ce scénario? –

0

Vous pouvez ajouter une méthode abstraite à ActionBase qui renvoie un ActionDescriptor, puis vous pouvez interroger chaque action pour son descripteur.

+0

Dan, je devrais toujours obtenir une liste d'actions. –

+0

Droite. Je travaille avec un projet qui utilise quelque chose comme un ActionManager avec lequel chaque action s'inscrit lors de la création. Le Mgr peut ensuite être interrogé pour la liste des actions. – DanJ

+0

J'ai déjà implémenté ce modèle.Le bit que je n'aime pas c'est que toutes les actions doivent être artificiellement instanciées afin de les faire s'auto-enregistrer. –