Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change enum definition without impacting clients using it in C#

Tags:

c#

c#-3.0

I have the following enum defined. I have used underscores as this enum is used in logging and i don't want to incur the overhead of reflection by using custom attribute.We use very heavy logging. Now requirement is to change "LoginFailed_InvalidAttempt1" to "LoginFailed Attempt1". If i change this enum, i will have to change its value across application. I can replace underscore by a space inside logging SP. Is there any way by which i can change this without affecting whole application.Please suggest.

public enum ActionType
{
    None,
    Created,
    Modified,
    Activated,
    Inactivated,
    Deleted,
    Login,
    Logout,
    ChangePassword,
    ResetPassword,
    InvalidPassword,
    LoginFailed_LockedAccount,
    LoginFailed_InActiveAccount,
    LoginFailed_ExpiredAccount,
    ForgotPassword,
    LoginFailed_LockedAccount_InvalidAttempts,
    LoginFailed_InvalidAttempt1,
    LoginFailed_InvalidAttempt2,
    LoginFailed_InvalidAttempt3,
    ForgotPassword_InvalidAttempt1,
    ForgotPassword_InvalidAttempt2,
    ForgotPassword_InvalidAttempt3,
    SessionTimeOut,
    ForgotPassword_LockedAccount,
    LockedAccount,
    ReLogin,
    ChangePassword_Due_To_Expiration,
    ChangePassword_AutoExpired

}
like image 414
Rohit Raghuvansi Avatar asked Jun 14 '10 12:06

Rohit Raghuvansi


People also ask

Can we change value of enum in C?

You can change default values of enum elements during declaration (if necessary).

Can enum values be changed?

Enum constants are final but it's variable can still be changed. For example, we can use setPriority() method to change the priority of enum constants. We will see it in usage in below example. Since enum constants are final, we can safely compare them using “==” and equals() methods.

Can you override an enum?

By default, the enum value is its method name. You can however override it, for example if you want to store enums as integers in a database, instead of using their method name. An enum value doesn't have to be a string, as you can see in the example.


1 Answers

The best way to do it will be with a Description attribute. I understand that you don't use reflection, but you can always cache the result so it only happens once?

Add the description attribute:

[Description("LoginFailed Attempt1")]
LoginFailed_InvalidAttempt1

Then when displaying the text value of the enum, you can get the description out using the following bit of code:

private static Dictionary<Type, Dictionary<Enum, string>> enumMaps = null;

public static string GetDescription(Enum value)
{
    Type eType = value.GetType();
    if (enumMaps == null)
    {
        enumMaps = new Dictionary<Type, Dictionary<Enum, string>> ();
    }
    Dictionary<Enum, string> map;
    if (enumMaps.ContainsKey(eType))
    {
        map = enumMaps[eType];
    }
    else
    {
        map = new Dictionary<Enum, string>();
        foreach (Enum e in Enum.GetValues(eType))
        {
            FieldInfo fi = eType.GetField(e.ToString());
            DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(
                typeof(DescriptionAttribute), false);
            map[e] = (attributes.Length > 0) ? attributes[0].Description : e.ToString();
        }
        enumMaps[eType] = map;
    }
    return map[value];
}

As you can see from the code above, the reflection is only done once. Any subsequent calls on the same Enum value will return the result from a Dictionary which is lightning fast.

like image 107
djdd87 Avatar answered Oct 06 '22 12:10

djdd87