Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何更改枚举定义而不影响在C中使用它的客户端#_C#_C# 3.0 - Fatal编程技术网

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

C# 如何更改枚举定义而不影响在C中使用它的客户端#,c#,c#-3.0,C#,C# 3.0,我定义了以下枚举。我使用了下划线,因为这个枚举用于日志记录,我不想通过使用自定义属性引起反射的开销。我们使用非常繁重的日志记录。现在的要求是将“LoginFailed\u InvalidatedTest1”更改为“LoginFailed Attempt1”。如果更改此枚举,则必须在整个应用程序中更改其值。我可以在logging SP中用空格替换下划线。是否有任何方法可以在不影响整个应用程序的情况下更改下划线。请建议 public enum ActionType { None, C

我定义了以下枚举。我使用了下划线,因为这个枚举用于日志记录,我不想通过使用自定义属性引起反射的开销。我们使用非常繁重的日志记录。现在的要求是将“LoginFailed\u InvalidatedTest1”更改为“LoginFailed Attempt1”。如果更改此枚举,则必须在整个应用程序中更改其值。我可以在logging 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

}

最好的方法是使用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];
}
private static Dictionary enumMaps=null;
公共静态字符串GetDescription(枚举值)
{
类型eType=value.GetType();
如果(enumMaps==null)
{
enumMaps=新字典();
}
词典地图;
if(enumMaps.ContainsKey(eType))
{
map=enumMaps[eType];
}
其他的
{
map=新字典();
foreach(Enum.GetValues(eType)中的枚举e)
{
FieldInfo fi=eType.GetField(例如ToString());
DescriptionAttribute[]属性=(DescriptionAttribute[])fi.GetCustomAttributes(
typeof(DescriptionAttribute),false);
映射[e]=(attributes.Length>0)?属性[0]。说明:e.ToString();
}
enumMaps[eType]=映射;
}
返回映射[值];
}

从上面的代码可以看出,反射只执行一次。对同一枚举值的任何后续调用都将从一个迅雷不及掩耳的
字典返回结果。

您可以使两个枚举值具有相同的整数,并将其中一个标记为过时:

public enum MyEnum {
    Value1,
    Value2,

    [Obsolete]
    Value3,

    NewValue3 = Value3,
}

那么这有什么帮助呢?我的理解是OP希望能够输出“LoginFailed Attempt1”而不是“LoginFailed_1”。由于不能在枚举名中放置空格,我不知道这是如何解决问题的?或者我可能弄错了;当您查询“testValue”时,您得到的是Value3,而不是“NewValue3”,但是您可以在Value2之后立即添加NewValue3,这将解决此问题。将新值四舍五入,然后-过时的值放在枚举定义的末尾。您是说要输出友好的枚举名称来代替枚举吗?或者您是说要用名称中带有空格的枚举替换实际的枚举名称?我想将LoginFailed_InvalidateTest1转换为Login Failed Attempt1。。你说的“从转换”是什么意思?@Rohit,这些描述第一次就反映出来了(这是比较慢的部分),之后,结果是来自字典,所以速度非常快。我想这会解决你的问题。是的,除了第一次,它的速度非常快。感谢这么好的一段代码。它实际上帮助我们做很多不同的事情。