2014-04-28 48 views
3

我嘗試使用枚舉ToString方法顯示枚舉值。 該枚舉具有Flags屬性。如何使用flags屬性將枚舉格式化爲十六進制值?

有值不符合枚舉值的任何組合。
在這種情況下,ToString返回數字作爲十進制,但我想顯示它爲十六進制字符串。

使用ToString("X8")將始終返回十六進制值。我試過Enum.IsDefined,但它只在非組合值上返回true。

例子:

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

問:如何"ToString"未知枚舉值作爲十六進制值?

+1

我在過去使用過類似的自定義'TypeConverter'。如果今晚還在等待答案,我會把它挖掘出來。 – ClickRick

+0

醜陋的解決方案:使用'ToString',然後如果結果包含數字︰使用'ToString(「X8」)' – MrFox

+0

@mrfox:我也想過這個,但是 - 正如你所說 - 這將是醜陋的... – joe

回答

3

您可以檢查是否值已設置爲大於標誌枚舉的總位掩碼的其他位。如果是這樣,請返回數字,否則返回正常的數據字符串:

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"); 
} 
+0

好做法。在我的情況下,這個確切的解決方案不起作用,因爲某些枚舉值具有相同的位集,所以總結這些值會導致錯誤的'enumtotal'。但是,對所有值使用'foreach'循環並對其進行「或」運算可以解決這個問題。 – joe

+1

@Joe,很高興它是有用的,並聽取你有關聯合枚舉值。更改了代碼以使用一個或多個''而不是總和的聚合以備將來參考。 –

0

您需要編寫自己的字符串轉換例程,但不能爲枚舉重寫ToString()。爲了格式化[國旗]看System.Enum.InternalFlagsFormat:

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 
    } 
相關問題