Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

When Enum is used as below, say if we have

enum Designation
{
    Manager = 0,
    TeamLead = 1,
    Associate = 2
}

then write the below code

if (designation == Designation.TeamLead) //somecode

Now if we decide to change the enum element from "TeamLead" to "Lead" then we have to modify the above line of code as well i.e. designation == Designation.TeamLead to designation == Designation.Lead. So what is the best practice.

share|improve this question
9  
Not exactly relevant to what you're asking, but a best practice is to have 0 as None –  superM May 13 '13 at 14:03
4  
Best practice with regard to what? What is the question? What are you concerned about? –  Konrad Morawski May 13 '13 at 14:14
1  
Do you mean "is it a best practice to use enums" in general? You don't appear to be doing anything specific with them, just generally..using them... so, is that all you're curious about? –  Jimmy Hoffa May 13 '13 at 14:18
4  
This is why you use enum so you CAN rename them. VS renaming tools work just fine on enum. –  Mathew Foscarini May 13 '13 at 14:47
2  
Why do you explicitly assign the values 0, 1, and 2 (which are the default values anyway)? Are you going to write code that depends on Associate having the value 2? What would you lose by writing enum Designation { Manager, TeamLead, Associate }? –  Keith Thompson May 13 '13 at 17:18
show 1 more comment

6 Answers

up vote 16 down vote accepted

The most basic answer to your question is this: Most C# IDEs I know of have a Refactoring option that easily lets you rename variables and references, such as enum types. If you highlight TeamLead, anywhere it's used, right-click it and look for a Rename option, you should be able to change references in all code files of your project. If you reference it as a string at some point, it may be good to do a full text search and handle individual cases.

However, my full answer, which I can only hope you care about, is that this is the wrong way of going about things in an object-oriented language. You should especially take note of times when you're seperating large blocks of logic by an if-else/switch, and even using part of one block in another, as a time when object-oriented design would help you. Here's how I'd do it, in incomplete pseudo-code:

abstract class ProjectMember {
    public abstract void reassignTask(Task t);
}

class Manager : ProjectMember {
    public void reassignTask(Task t) {
        // TODO: manager case
    }
}

class TeamLead : ProjectMember {
    public void reassignTask(Task t) {
        // TODO: TeamLead case
    }
}

class Associate : ProjectMember {
    public void reassignTask(Task t) {
        // TODO: associate case
    }
}


// this is the function where you'd be getting rid of a switch statement, by way of the above code.
void reassignMemberTask(ProjectMember mem, Task t) {
    mem.reassignTask(t);
}
share|improve this answer
3  
This sounds more reasonable and thanks Katana. –  sameer May 13 '13 at 14:53
1  
Well, then you'd have a Team class, and an instance of that in your ProjectMember class. Then, you can have code specific to that Team. I was also going under the assumption that this was hardly the only enum-selecting piece of code they were going to have. It's especially useful if you have, for instance, a TeamLeadAssistant class that's just a tiny functional modification of TeamLead. If the project uses these often, then it becomes less and less of an overkill. –  Katana314 May 13 '13 at 15:30
1  
switch statements are procedural overkill more often than not. Object dispatch exists exactly for this reason, but there needs to be sufficient amount of code in the different switch cases (or sufficient proof they are a part of the system that will surely grow and change with time) to prove necessity for an object hierarchy. This usually is the right way to go though. –  Jimmy Hoffa May 13 '13 at 15:39
1  
@Katana314 Nicely done. I agree with your approach. Too often I have seen methods such as reassignTask that contain massive switch statements or if/else that evaluate every permutation of an enum. –  Chuck Conway May 13 '13 at 15:42
1  
By the time you've got a number of switch statements it's too risky to change the switch statements (there is something to be said for working code, testable or not). If the application is not a proof of concept (POF) or not a throw away application us an object hierarchy. –  Chuck Conway May 13 '13 at 15:54
show 2 more comments

Renaming an element of an enum is not a problem: Visual Studio does that for you, while ensuring that every reference to it will be renamed as well.

On the other hand, other issues may arise when "reusing" the elements in such way:

  1. Business behavior

    Imagine that TeamLead is a team lead, while Lead is a lead developer in a team. Imagine the following piece of code:

    if (role != Designation.TeamLead)
    {
        // The user cannot fire a member of a team: only a team lead can do it.
        this.DenyFiringTeamMember();
    }
    

    If you rename the role, you will miss the business rules, i.e. the fact that only a team lead can fire a team member. Now, lead developer can fire other developers, while only team lead is expected to be able to do it.

  2. Dependencies

    Unless you're Google, you may have dependencies in external projects. Visual Studio won't be able to find those, so the problem will arise the next time you open a solution which is referencing the old TeamLead.

  3. ToString

    Sometimes, and this is an extremely bad practice, the item from the enum is converted to string, and then used in a comparison, or stored in database, etc. Example:

    if (role.ToString() == "TeamLead")
    {
        // I never understood how to compare variables, and I don't care.
    }
    

    Renaming the element will break those pieces of code. Maybe it's better: you'll be able to find them and rewrite them correctly.

share|improve this answer
add comment

Just use a refactoring tool. You cannot circumvent the fact that if you rename something you have to rename it everywhere but a refactoring tool will make that easy.

share|improve this answer
    
Why the down vote? –  Sarien May 13 '13 at 14:25
1  
+1 I don't know why you got downvoted. It's a reasonable answer. –  Chuck Conway May 13 '13 at 15:46
    
@ChuckConway well - I have not downvoted it, but it doesn't really answer the question. The question is poorly phrased anyhow, but it's clearly asking about best practices (the author just failed to specify what he is concerned about). He's asking about what he should do, not how. –  Konrad Morawski May 14 '13 at 11:34
add comment

Most refactoring tools can easily help with this. It allows mass renaming based on language semantics, not only text-replace.

But if you use complex enums for business logic, I would start thinking if you shouldn't be using proper OOP.

share|improve this answer
    
+1 I don't know why you got downvoted. It's a reasonable answer. –  Chuck Conway May 13 '13 at 15:48
add comment

If you rename the enum member in a DLL, the caller code needs to be modified and recompiled.

This may break binary compatibility. You need to ensure the caller code is possible to be modified.

share|improve this answer
    
Only relevant if the enum is public. –  Marcel May 14 '13 at 6:37
add comment

I will answer, not because I think the other answers are bad, but because I think there is another thing to be said in this case.

We have two questions in one:

  1. About best practice for you Enum
  2. About refactoring an Enum

1)Is this a Best Practice with Enum in C#?

Well, in your case, since you Enum seems to be kind of hierarchic, I would define them as flags, and benefit from that when using and comparing the values.

[Flags]
enum Designation
{
    None = 0x0,
    TeamLead = 0x1,
    Manager = 0x2,
    Associate = 0x4
}

Then you could use a code like this:

    string CheckAboveManager(Designation designation)
    {
        if (designation >= Designation.Manager)
            return "It's a manager or higher";
        return "Is lower than manager";
    }

The other option of using a object-oriented structure will work only if there is specific behavior or structure you want to separate concerns with. If it is a case of just defining a property (that why there are enums!), them I see no need to create inheritance, but if it is the case, use the accepted answer.

2) Now if we decide to change the enum element from "TeamLead" to "Lead" then we have to modify the above line of code as well i.e. designation == Designation.TeamLead to designation == Designation.Lead

Well, it was already well explained that refactoring is not an issue if you are using VS IDE, you can even use other tools like DevExpress CodeRush! or ReSharper to get an even better (and very safe) result from refactoring.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.