2010-10-12 141 views
5

一直在談論枚舉一般違反清潔代碼原則,所以我正在尋找人們最喜歡的枚舉反模式和替代解決方案。C#:枚舉反模式

比如我見過這樣的代碼:

switch(enumValue) { 
    case myEnum.Value1: 
     // ... 
     break; 
    case myEnum.Value2: 
     // ... 
     break; 
} 

這一步比魔術串行中的開關語句更好,但是這可能會被解決了工廠,容器或其他模式更好。

甚至老派這樣的代碼:

if(enumValue == myEnum.Value1) { 
    // ... 
} else if (enumValue == myEnum.Value2) { 
    // ... 
} 

你用枚舉經歷了哪些反模式,更好的實現?

+4

字典比Enum好?你能解釋爲什麼嗎? – 2010-10-12 10:11:42

+5

你完全混合了一切。反對枚舉的'switch'本身並不壞。有時候這是必要的,例如在提到的工廠。 – Andrey 2010-10-12 10:22:03

+0

您應該使用帶有枚舉鍵的字典。這樣你就可以得到兩全其美的效果:強類型的字典和沒有更長的開關語句。 – VitalyB 2010-10-12 10:26:13

回答

11

我覺得枚舉是非常有用的。我已經寫了已經加入了更多的價值及其使用

首先,枚舉了一些擴展,還有的描述擴展方法

public static class EnumExtensions 
{ 
    public static string Description(this Enum value) 
    { 
     var entries = value.ToString().Split(ENUM_SEPERATOR_CHARACTER); 
     var description = new string[entries.Length]; 
     for (var i = 0; i < entries.Length; i++) 
     { 
      var fieldInfo = value.GetType().GetField(entries[i].Trim()); 
      var attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false); 
      description[i] = (attributes.Length > 0) ? attributes[0].Description : entries[i].Trim(); 
     } 
     return String.Join(", ", description); 
    } 
    private const char ENUM_SEPERATOR_CHARACTER = ','; 
} 

這將讓我定義的連接枚舉是這樣的:

public enum MeasurementUnitType 
{ 
    [Description("px")] 
    Pixels = 0, 
    [Description("em")] 
    Em = 1, 
    [Description("%")] 
    Percent = 2, 
    [Description("pt")] 
    Points = 3 
} 

並通過執行此操作獲取標籤:var myLabel = rectangle.widthunit.Description()(不需要任何switch語句)。

如果rectangle.widthunit = MeasurementUnitType.Pixels這將雙向返回「px」,或者如果rectangle.widthunit = MeasurementUnitType.Pixels | MeasurementUnitType.Em它將返回「px,em」。

然後,有一個

public static IEnumerable<int> GetIntBasedEnumMembers(Type @enum) 
    { 
     foreach (FieldInfo fi in @enum.GetFields(BindingFlags.Public | BindingFlags.Static)) 
      yield return (int)fi.GetRawConstantValue(); 
    } 

,這將讓我穿越與詮釋基於價值的任何枚舉,並返回INT值本身。

我發現這些在一個有用的概念中非常有用。

+0

我們不是用一個字典更簡單的代碼來做它嗎?上面的代碼帶來了什麼價值? – 2010-10-12 11:08:47

+3

@Seb:幾個原因:首先,如果您使用字典,則說明位於聲明旁邊,而不是其他位置。其次,描述總是與枚舉類型一起呈現,這導致...最後,類型可以導入到另一個程序集中,並且枚舉值及其描述可以反映並呈現給用戶(對編輯有用我已經搞定了)。 – Skizz 2010-10-12 11:22:57

+0

感謝Skizz,爲了節省我的時間;)幹得好。 – danijels 2010-10-12 11:38:27

0

在非反模式中使用枚舉。在一些關於重構的書中,這段代碼用來演示如何用多態性代替它。在代碼中過度使用枚舉時可以。

+1

這不是所說的。我詢問了涉及枚舉的反模式。 – 2010-10-12 10:38:18

1

這不是一個答案,就像貢獻Enum反模式列表一樣。

在今天上午的代碼審查期間,我遇到了類似以下的情況,都在同一個班級。

兩種情況:

  1. 之前喝

後..

public enum ListEnum 
    { 
     CategoryOne, 
     CategoryTwo, 
     CategoryThree, 
     CategoryFour 
    } 


    public class UIELementType 
    { 
     public const string FactoryDomain = "FactoryDomain"; 
     public const string Attributes = "Attributes"; 
    }