如何在不影响使用C#中枚举的客户端的情况下更改枚举定义

5
我已经定义了以下枚举。由于该枚举在日志记录中使用,我使用下划线,并且不想使用自定义属性而产生反射开销。我们进行了非常重的日志记录。现在的要求是将“LoginFailed_InvalidAttempt1”更改为“LoginFailed Attempt1”。如果我更改此枚举,我将不得不在整个应用程序中更改其值。我可以在日志记录SP内部将下划线替换为一个空格。是否有任何方法可以在不影响整个应用程序的情况下更改此内容?请给予建议。
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

}

你是要输出一个友好的枚举名称来代替枚举吗?还是说你想使用带空格命名的枚举来替换实际的枚举名称? - djdd87
我想将"LoginFailed_InvalidAttempt1"转换成"登录失败 尝试1" - Rohit Raghuvansi
“convert from” 是什么意思? - djdd87
2个回答

9
最好的方法是使用Description属性。我知道你不使用反射,但你可以始终缓存结果,这样只会发生一次?请添加description属性:
[Description("LoginFailed Attempt1")]
LoginFailed_InvalidAttempt1

然后,当显示枚举的文本值时,您可以使用以下代码获取描述:

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];
}

从上面的代码可以看出,反射只会执行一次。对于同一个枚举值的后续调用将返回来自Dictionary的结果,这非常快速。


1
@Rohit,描述仅在第一次反映(这是慢的部分),之后结果来自字典,因此非常快。我认为这将解决你的问题。 - SWeko
是的,它非常快,除了第一次。感谢这么棒的代码。它实际上帮助我们以不同的方式完成很多事情。 - Rohit Raghuvansi

0

你可以让两个枚举值拥有相同的整数值,并标记一个为过时:

public enum MyEnum {
    Value1,
    Value2,

    [Obsolete]
    Value3,

    NewValue3 = Value3,
}

那么 MyEnum.Value3 == MyEnum.NewValue3



这有什么帮助呢?我的理解是OP想要在"LoginFailed_InvalidAttempt1"的位置输出"LoginFailed Attempt1"。由于您无法在枚举名称中放置空格,我不明白这如何解决问题?或者我可能误解了。 - djdd87
MyEnum testValue = MyEnum.NewValue3; 当你查询"testValue"时,你会得到Value3,而不是"NewValue3"然而,你可以在Value2之后立即添加NewValue3来解决这个问题。 - openshac
1
交换新值,然后将过时的值放在枚举定义的末尾。 - thecoop

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接