2010-10-12 73 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"; 
    }