C# naming convention for enum and matching property

49,308

Solution 1

I'll add my 1 euro to the discussion but it's probably not adding anything new.

The obvious solution is to move Status out of being a nested Enum. Most .NET enums (except possibly some in Windows.Forms namespace) aren't nested and it makes it annoying to use for the developer consuming your API, having to prefix the classname.

One thing that hasn't been mentioned is that flag enums according to MSDN guidelines should be pluralized nouns which you probably already know (Status is a simple enum so singular nouns should be used).

State (enum called States) is the vocative, "Status" is the nominative of a noun that the English like most of our language absorbed from Latin. Vocative is what you name a noun for its condition and nominative is the subject of the verb.

So in other words when the car is moving, that's the verb - moving is its status. But the car doesn't go off, its engine does. Nor does it start, the engine does (you probably picked an example here so this might be irrelevant).

public class Car
{
  VehicleState _vehicleState= VehicleState.Stationary;

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

public enum VehicleState
{
    Stationary, Idle, Moving
}

State is such a generalised noun wouldn't it be better to describe what state it is referring to? Like I did above

The type example also in my view doesn't refer to the reader type, but its database. I would prefer it if you were describing the reader's database product which isn't necessarily relevant to the type of reader (e.g. the type of reader might be forward only, cached and so on). So

reader.Database = Databases.Oracle;

In reality this never happens as they're implemented as drivers and an inheritance chain instead of using enums which is why the line above doesn't look natural.

Solution 2

The definition of "Off", "Starting" and "Moving" is what i would call a "State". And when you are implying that you are using a "State", it is your "Status". So!

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

  State state = State.Off;

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

If we take another example from the one stated where you'd like to use the word "Type" such in this case:

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

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

}

You really need to see that there is a difference between enums and enums, right? But when creating a framework or talking about architecture you need to focus on the simillarities, ok lets find them:

When something is set to a State, it's defined as the "things" Status

Example: The Car's Status is in Running State, Stopped State, and so on.

What you want to acheive in the second example is somewhat this:

myDataReader.Type = DataReader.Database.OleDb

You might think that this says against what i've been preaching about to others, that you need to follow a standard. But, you are following a standard! The Sql-case is a specific case aswell and therefore need a somewhat specific solution.

However, the enum would be re-usable within your System.Data space, and that's what the patterns is all about.

Another case to look at with the "Type" is "Animal" where Type defines the Species.

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

        public Type Species{ get; set; }

    }

This is following a pattern, you don't specificly need to "know" the Object for this and you are not specifing "AnimalType" or "DataReaderType", you can re-use the enums in your namespace of choice.

Solution 3

I think the real problem here is that the enum Status is encapsulated within your class, such that Car.Status is ambiguous to both the property Status and the enum Status

Better yet, put your enum outside of the class:

public enum Status
{
    Off,
    Starting,
    Moving
}

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

UPDATE

Due to the comments below, I'll explain my design above.

I'm one who doesn't believe that enums or classes or any other object should reside inside another class, unless it will be totally private within that class. Take the above example, for instance:

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

While some commenters would argue that Status doesn't have any meaning outside the scope of the class Car, the fact that you are setting a public property means that there are other parts of the program that will use that enum:

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

And that to me is a code smell. If I'm going to look at that status outside of Car, I might as well define it outside as well.

As such, I will probably just rename it as:

public enum CarStatus
{...}

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

However, if that enum will be used within and only within the car class, then I'm fine with declaring the enum there.

Solution 4

Haters of Hungarian notation and its variants be damned. I use a convention of suffixing enums with - wait for it - Enum. I consequently never have the problem you describe, waste time worrying about what to call them and the code is readable and self-descriptive to boot.

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

  public StatusEnum Status { get; set; }

}

Solution 5

I'd change the name of the property to something like "CurrentStatus". Quick an easy :)

Share:
49,308
Serge Wautier
Author by

Serge Wautier

Self appointed Internationalization Specialist, author of appTranslator, which was once a great tool to translate the UI of your programs. No longer since I never took the necessary time to keep it up with recent frameworks... Currently managing a great team that develops and operates Talk2M: One of the largest OpenVPN setup worldwide (Yes sir!)

Updated on July 12, 2020

Comments

  • Serge Wautier
    Serge Wautier almost 4 years

    I often find myself implementing a class maintaining some kind of own status property as an enum: I have a Status enum and ONE Status property of Status type. How should I solve this name conflict?

    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(); }
      }
    }
    

    If the Status enum were common to different types, I'd put it outside the class and the problem would be solved. But Status applies to Car only hence it doesn't make sense to declare the enum outside the class.

    What naming convention do you use in this case?

    NB: This question was partially debated in comments of an answer of this question. Since it wasn't the main question, it didn't get much visibility.

    EDIT: Filip Ekberg suggests an IMO excellent workaround for the specific case of 'Status'. Yet I'd be interesting to read about solutions where the name of the enum/property is different, as in Michael Prewecki's answer.

    EDIT2 (May 2010): My favorite solution is to pluralize the enum type name, as suggested by Chris S. According to MS guidelines, this should be used for flag enums only. But I've come to like it more and more. I now use it for regular enums as well.

  • Dan C.
    Dan C. over 15 years
    I believe the "Status" name was just an example. What about other situations, when you can't rely on Status/State? E.g. a Type enum...
  • Filip Ekberg
    Filip Ekberg over 15 years
    Could you please provide an example scenario for that? ill try to expand my answer according to that aswell :)
  • annakata
    annakata over 15 years
    the Namespacing from the class should be enough to deal with this anyway
  • Filip Ekberg
    Filip Ekberg over 15 years
    That would make Status global, you might want to have it just inside a specific area. "Status" for other types such as "Human" might not have "Starting". But you should follow a pattern.
  • Quibblesome
    Quibblesome over 15 years
    No he's spot on. The enum is in 99% of the cases the same word you want to use for the property. An enum is just a named flag so it does little harm in living outside (unlike classes which contain logic)
  • Serge Wautier
    Serge Wautier over 15 years
    Jon, this is precisely my point: the Status enum is meaninful only regarding Car. Totally different types of objects will have totally different statuses
  • Filip Ekberg
    Filip Ekberg over 15 years
    I hope the addition to my answer provides some points on how to structure your work, my point being that you can't really generalise all cases :)
  • Filip Ekberg
    Filip Ekberg over 15 years
    Sorry should be Species. English is not my native language so still lack some words :)
  • Jon Limjap
    Jon Limjap over 15 years
    I don't like the idea of defining types within a class when it will be used by the program outside of that class in the first place. Also, be reminded that the word "Type" is a reserved keyword in C# ;)
  • Serge Wautier
    Serge Wautier over 15 years
    My understanding is that flags should be pluralized, not simple enums.
  • Serge Wautier
    Serge Wautier over 15 years
    regarding moving enums out of the class, I have yet to understand why CarState is more convenient than Car.State. However, I don't understand the positive side of getting an enum out of a class when this enum describes the behaviour of this class only.
  • MordechayS
    MordechayS over 15 years
    I should've written noun phrases like FileOptions not just nouns, I've updated the answer. I suppose classname.Enum is just a preference - I can't find any examples in the framework which what I end up copying.
  • Dan C.
    Dan C. over 15 years
    @Filip: the Animal Type sample points out exactly what I meant in the first comment, i.e. this is pretty much "rewording" of the enum. Using synonyms for the enum and the property name makes the code somewhat confusing, I think.
  • LegendLength
    LegendLength almost 15 years
    I also think 'species' is just a rewording of type (for animals in this case).
  • annakata
    annakata over 14 years
    Simply renaming isn't always that clean - think of a class for a playing card for example, with an enum Suit and a property Suit - rename to what exactly? Clumsy either way.
  • Serge Wautier
    Serge Wautier over 14 years
    Even though MS says that plural should be kept for flags, over the time, I've come to like that solutions more and more. I now use it for enums as well. Hence I changed my mind and accepted your answer instead of Filip's.
  • Filip Ekberg
    Filip Ekberg over 14 years
    There are of course special cases where simply renaming in the current context wont help. But in general cases it's enough to do as i did. Rembmer, naming convetions are there to Help others know your code without ever having to programmed against it. That's at least what you aim against when designen an API. So if the user does Cards.Shuffle(); Card.Pick() == Card.Deck.Heart.Suite, that doesnt look to nice. However, it might be what the end user enticipates.
  • David Murdoch
    David Murdoch over 13 years
    I know I'm 1 1/2 years late here, but public class EngineState should be public enum EngineState in the example, right?
  • Avi
    Avi over 13 years
    English is a foreign lang for me, but I thing the engine is running, the car is moving.
  • deed02392
    deed02392 over 10 years
    The explanation that wanting to look at it outside of Car makes sense. But in my case I have two classes, OR and CR. Both have their own set of states, so it's not an option to define them outside their own scope.
  • DavidRR
    DavidRR almost 10 years
    Please be aware though that Microsoft's conventions for Naming Enumerations says: X DO NOT use an "Enum" suffix in enum type names.
  • nathanchere
    nathanchere over 9 years
    Because Microsoft's conventions have been proven to stand the test of time.
  • Boogier
    Boogier almost 8 years
    this approach leads to misunderstanding and muddles the code