如何使用flags属性将枚举格式化为十六进制值?

时间:2014-04-28 12:26:29

标签: c# enums tostring flags

我尝试使用枚举ToString方法显示枚举值。 枚举具有Flags属性。

有些值与枚举值的任何组合都不匹配 在这种情况下,ToString将数字作为十进制返回,但我想将其显示为十六进制字符串。

使用ToString("X8")将始终返回十六进制值。

我尝试了Enum.IsDefined,但只返回非组合值的true。

示例:

0x00000201 -> "XXt, TSW_AUTO_DETECT"   (known values)
0x00010108 -> "00010108"               (unknown value)

问:如何将"ToString" 未知枚举值作为十六进制值?

2 个答案:

答案 0 :(得分:3)

您可以检查该值是否设置了任何其他位而不是flags枚举的总位掩码。如果是这样,请返回数字,否则返回正常的tostring:

public static string GetDescription(EnumName value)
{
    var enumtotal = Enum.GetValues(typeof(EnumName)).Cast<int>().Aggregate((i1, i2) => i1 | i2); //this could be buffered for performance
    if ((enumtotal | (int)value) == enumtotal)
        return value.ToString();
    return ((int)value).ToString("X8");
}

答案 1 :(得分:0)

您需要编写自己的字符串转换例程,不能为枚举重写ToString()。为了格式化[Flags],请查看System.Enum.Internal FlagsFormat:

private static String InternalFlagsFormat(RuntimeType eT, Object value)
    {
        Contract.Requires(eT != null);
        Contract.Requires(value != null); 
        ulong result = ToUInt64(value);
        HashEntry hashEntry = GetHashEntry(eT); 
        // These values are sorted by value. Don't change this 
        String[] names = hashEntry.names;
        ulong[] values = hashEntry.values; 
        Contract.Assert(names.Length == values.Length);

        int index = values.Length - 1;
        StringBuilder retval = new StringBuilder(); 
        bool firstTime = true;
        ulong saveResult = result; 

        // We will not optimize this code further to keep it maintainable. There are some boundary checks that can be applied
        // to minimize the comparsions required. This code works the same for the best/worst case. In general the number of 
        // items in an enum are sufficiently small and not worth the optimization.
        while (index >= 0)
        {
            if ((index == 0) && (values[index] == 0)) 
                break;

            if ((result & values[index]) == values[index]) 
            {
                result -= values[index]; 
                if (!firstTime)
                    retval.Insert(0, enumSeperator);

                retval.Insert(0, names[index]); 
                firstTime = false;
            } 

            index--;
        } 

        // We were unable to represent this number as a bitwise or of valid flags
        if (result != 0)
            return value.ToString(); 

        // For the case when we have zero 
        if (saveResult==0) 
        {
            if (values.Length > 0 && values[0] == 0) 
                return names[0]; // Zero was one of the enum values.
            else
                return "0";
        } 
        else
        return retval.ToString(); // Return the string representation 
    }