90 votes

Convention de dénomination C# pour les enum et les propriétés correspondantes

Je me retrouve souvent à implémenter une classe qui maintient une sorte de propriété d'état propre sous forme d'énumération : J'ai un enum Status et UNE propriété Status de type Status. Comment dois-je résoudre ce conflit de noms ?

public class Car
{
  public enum Status
  {
    Off,
    Starting,
    Moving
  };

  Status status = Status.Off;

  public Status Status // <===== Won't compile =====
  {
    get { return status; }
    set { status = value; DoSomething(); }
  }
}

Si l'enum Status était commun à différents types, je le placerais en dehors de la classe et le problème serait résolu. Mais le statut ne s'applique qu'à la voiture et il n'est donc pas logique de déclarer l'enum en dehors de la classe.

Quelle convention de dénomination utilisez-vous dans ce cas ?

NB : Cette question a été partiellement débattue dans les commentaires d'une réponse de cette question . Comme ce n'était pas le principal question, il n'a pas eu beaucoup de visibilité.

EDIT : Filip Ekberg propose une excellente solution de contournement pour le cas spécifique de "Status". Cependant, je serais intéressé de lire des solutions où le nom de l'enum/de la propriété est différent, comme dans l'article de Michael Prewecki intitulé réponse .

EDIT2 (mai 2010) : Ma solution préférée est de mettre le nom du type d'enum au pluriel, comme suggéré par Chris S. Selon les directives de MS, cela ne devrait être utilisé que pour les flag enums. Mais j'ai fini par l'apprécier de plus en plus. Je l'utilise maintenant pour les enums réguliers aussi.

34voto

Filip Ekberg Points 22189

La définition de "Arrêt", "Démarrage" et "Déplacement" est ce que j'appellerais un "État". Et lorsque vous laissez entendre que vous utilisez un "État", il s'agit de votre "Statut". Donc !

public class Car
{
  public enum State
  {
    Off,
    Starting,
    Moving
  };

  State state = State.Off;

  public State Status
  {
    get { return state ; }
    set { state= value; DoSomething(); }
  }
}

Si nous prenons un autre exemple de celui énoncé où vous voudriez utiliser le mot "Type" comme dans ce cas :

public class DataReader
{
    public enum Type
    {
        Sql,
        Oracle,
        OleDb
    }

    public Type Type { get; set; } // <===== Won't compile =====

}

Vous avez vraiment besoin de voir qu'il y a une différence entre les enums et les énumérations, n'est-ce pas ? Mais lorsque vous créez un cadre ou que vous parlez d'architecture, vous devez vous concentrer sur les similitudes, ok, trouvons-les :

Lorsqu'un élément est associé à un État, il est défini comme l'État "choses".

Exemple : La voiture est en état de marche, d'arrêt, et ainsi de suite.

Ce que vous voulez obtenir dans le deuxième exemple est en quelque sorte ceci :

myDataReader.Type = DataReader.Database.OleDb

Vous pourriez penser que cela va à l'encontre de ce que j'ai prêché aux autres, à savoir que vous devez suivre une norme. Mais, vous suivez une norme ! Le cas Sql est également un cas spécifique et nécessite donc une solution quelque peu spécifique.

Cependant, l'enum serait réutilisable dans votre System.Data l'espace, et c'est ce dont il s'agit avec les modèles.

Un autre cas à examiner avec le "Type" est "Animal" où le Type définit l'Espèce.

public class Animal
    {
        public enum Type
        {
            Mammal,
            Reptile,
            JonSkeet
        }

        public Type Species{ get; set; }

    }

Il s'agit de suivre un modèle, vous n'avez pas besoin de "connaître" spécifiquement l'objet pour cela et vous ne spécifiez pas "AnimalType" ou "DataReaderType", vous pouvez réutiliser les enums dans l'espace de nom de votre choix.

31voto

Chris S Points 32376

Je vais ajouter mon euro à la discussion, mais je n'apporterai probablement rien de nouveau.

La solution évidente est de faire en sorte que le statut ne soit plus un Enum imbriqué. La plupart des enums .NET (à l'exception peut-être de certains dans l'espace de noms Windows.Forms) ne sont pas imbriqués et cela rend leur utilisation ennuyeuse pour le développeur qui utilise votre API, car il doit préfixer le nom de la classe.

Une chose qui n'a pas été mentionnée est que les enums de drapeau selon les directives de MSDN devraient être des noms au pluriel que vous connaissez probablement déjà (le statut est une simple énumération, il faut donc utiliser des noms au singulier).

State (enum appelé States) est le vocatif, "Status" est le nominatif d'un substantif que l'anglais comme la plupart de notre langue a absorbé du latin. Le vocatif est ce que vous nommez un nom pour sa condition et le nominatif est le sujet du verbe.

En d'autres termes, quand la voiture est en mouvement c'est le verbe - le déménagement est son statut. Mais la voiture ne s'arrête pas, c'est son moteur qui le fait. Elle ne démarre pas non plus, c'est le moteur qui démarre (vous avez probablement choisi un exemple ici, donc cela peut ne pas être pertinent).

public class Car
{
  VehicleState _vehicleState= VehicleState.Stationary;

  public VehicleState VehicleState 
  {
    get { return _vehicleState; }
    set { _vehicleState = value; DoSomething(); }
  }
}

public enum VehicleState
{
    Stationary, Idle, Moving
}

État est un nom tellement généralisé qu'il ne serait pas préférable de décrire l'état auquel il se réfère ? Comme je l'ai fait ci-dessus

L'exemple du type ne fait pas non plus référence, à mon avis, au type de lecteur, mais à sa base de données. Je préférerais que vous décriviez le produit de la base de données du lecteur, qui n'est pas nécessairement pertinent pour le type de lecteur (par exemple, le type de lecteur peut être en avant seulement, en cache, etc.) Donc

reader.Database = Databases.Oracle;

En réalité, cela n'arrive jamais car ils sont implémentés comme des pilotes et une chaîne d'héritage au lieu d'utiliser des enums, c'est pourquoi la ligne ci-dessus ne semble pas naturelle.

9voto

Jon Limjap Points 46429

Je pense que le vrai problème ici est que l'enum Status est encapsulé dans votre classe, de telle sorte que Car.Status est ambiguë à la fois pour la propriété Status et l'enum Status

Mieux encore, placez votre enum en dehors de la classe :

public enum Status
{
    Off,
    Starting,
    Moving
}

public class Car
{
    public Status Status
    { ... }
}

UPDATE

En raison des commentaires ci-dessous, je vais expliquer ma conception ci-dessus.

Je suis de ceux qui ne croient pas que les enums, les classes ou tout autre objet doivent résider à l'intérieur de une autre classe, à moins qu'elle ne soit totalement privée au sein de cette classe. Prenons l'exemple ci-dessus :

public class Car
{
    public enum Status
    {...}
    ...
    public Status CarStatus { get; set;}
}

Certains commentateurs diront que le statut n'a pas de signification en dehors de la classe Car, mais le fait que vous définissiez une classe public signifie qu'il y a d'autres parties du programme qui sera utiliser cet enum :

public Car myCar = new Car();
myCar.CarStatus = Car.Status.Off;

Et que pour moi, c'est une odeur de code. Si je dois regarder ce statut à l'extérieur de de Car je pourrais aussi bien la définir à l'extérieur de également.

En tant que tel, je vais probablement le renommer comme suit :

public enum CarStatus
{...}

public class Car
{
    ...
    public CarStatus Status { get; set; }
}

Toutefois, si cet enum est utilisé dans le cadre de l'opération et seulement dans la classe voiture, alors je suis d'accord pour déclarer l'enum là.

4voto

nathanchere Points 2707

Que les détracteurs de la notation hongroise et de ses variantes soient damnés. J'utilise une convention qui consiste à suffixer les enums avec - attendez un peu - Enum . Par conséquent, je n'ai jamais eu le problème que vous décrivez, je n'ai pas perdu de temps à me demander comment les appeler et le code est lisible et auto-décrit.

public class Car
{
  public enum StatusEnum
  {
    Off,
    Starting,
    Moving
  };

  public StatusEnum Status { get; set; }

}

2voto

TWith2Sugars Points 2723

Je changerais le nom de la propriété en quelque chose comme "CurrentStatus". Rapide et facile :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X