2010-11-15 30 views
3

J'essaie de trouver la meilleure façon de réaliser mon design pour une énumération. Disons que j'ai une classe et ENUM:C# Enums vs Listes pilotées par les données

public enum ActionType 
{ 
    Acceptable = 1, 
    Unacceptable = 2, 
    PendingReview = 3   
} 
public class Report 
{ 
    public ActionType Action { get; set; } 
} 

Disons que j'ai aussi une table de base de données qui stocke les différents types d'action:

Id  Action 
1  Acceptable 
2  Unacceptable 
3  PendingReview 

si je veux ajouter un autre type d'action à une date ultérieure jour je devrais mettre à jour l'énumération et redéployer les assemblages. Mais j'adore la façon dont les enums réduisent les erreurs, facilitent la lecture du code et garantissent la compatibilité directe. Qu'est-ce qu'un moyen efficace d'adopter de nouveaux types d'actions?

Merci!

Répondre

2

J'ai aussi eu les mêmes problèmes que vous et j'ai essayé d'utiliser autant que possible les énumérations car cela rend la lisibilité un peu plus facile.

L'approche que j'ai utilisée est quelque peu redondante, mais j'ai créé une table de correspondance et j'ai utilisé une énumération miroir dans le code. Le problème avec l'utilisation des énumérations est que vous aurez des statuts sauvegardés dans la base de données qui sont déroutants et qui doivent être discernés dans la documentation. Le problème avec l'approche DB uniquement est que la lisibilité du code est sérieusement entravée et que vous aurez des instructions totalement illisibles comme if (status == 2) ...

De même, si un élément enum est ajouté, alors le flux de programme changera et le code devra être mis à jour de toute façon. Cela le rend plutôt inutile. Les stratégies de déploiement comme ClickOnce rendent le déploiement presque trivial.

+0

Des points très pratiques mon ami! Merci pour votre perspicacité! – adminJaxon

5

Si la valeur indique un changement dans le déroulement du programme, vous voulez qu'il reste enum. Stocker simplement la valeur numérique dans un champ de table.

Si la valeur ne change pas le flux du programme, il est préférable d'avoir une table de recherche où les valeurs potentielles sont extraites de la base de données.

On dirait que vous tombez dans la première catégorie. À ce stade, vous devrez déployer le code lorsque vous ajouterez des options afin que l'application sache quoi faire avec les nouvelles options.

+0

Merci! Cela prend tout son sens et oui, mes valeurs vont et pourront changer le cours de la logique. – adminJaxon

2

Il y a un terrain d'entente. Jetez un oeil à log4net.Core.Level (à partir de log4net, naturellement) pour un exemple de classe qui vous permet de créer quelque chose qui ressemble beaucoup à une énumération mais qui ne l'est pas.

Regardez here.

1

Nous avons certainement ce défi dans le projet sur lequel je travaille. Pour nous, l'avantage d'utiliser des énumérations en termes de lisibilité l'emportait sur la maintenance et nous avons donc essayé de trouver un moyen de vérifier nous-mêmes et de lever le drapeau lorsque quelque chose n'était pas correctement mis à jour.

La solution que nous utilisons est que nous avons des tests unitaires qui s'exécutent après chaque compilation pour valider les membres de l'enum et leurs valeurs de sauvegarde par rapport à la table de base de données associée à cette énumération.

L'un de ces tests unitaires pourrait ressembler à ceci:

[TestMethod] 
public void SomeLookupTest() 
{ 
    LookupGetter getter = new LookupGetter(); 

    LookupTester.CompareEnumWithDatabase(
     getter.GetItems(LookupName.Schema__SomeLookup), 
     typeof(SomeLookupEnumType) 
    ); 
} 
+0

J'aime ça! Très beau travail et merci pour la suggestion. – adminJaxon

+0

De rien.C'est l'une des meilleures solutions à ce genre de problème que j'ai vu - un bon compromis entre la facilité d'utilisation et la maintenabilité. – Shibumi