分组枚举最佳实践

时间:2015-06-11 12:27:15

标签: c# enums

如果你有一个枚举,其值可以自然地分组为子集。例如:

[Flags]
public enum Instrument
{
    Lute,
    Guitar,
    Flute,
    Drum
}
[Flags]
public enum InstrumentType
{
    Percussion,
    String,
    Wind,
}

有很多方法可以实现

1)将这些数据合并到一个单独的枚举?

[Flags]
public enum ValidInstrument
{
    Lute= Instrument.Lute| InstrumentType.String,
    Guitar = Instrument.Guitar | InstrumentType.String,
    Flute = Instrument.Flute | InstrumentType.Wind,
    Drum = Instrument.Drum | InstrumentType.Percussion,
}

(假设枚举之间有适当且没有交叉的值) 这将允许你做

(ValidInstrument | InstrumentType.String) == InstrumentType.String

确定乐器是否为字符串

2)创建某种完全相同的映射结构?

public static InstrumentType GetInstrumentType(Instrument inst)
{
    switch(inst)
    {
    case Instrument.Lute:
    case Instrument.Guitar:
        return InstrumentType.String
    //etc.
    }
}

3)属性?

public enum Instrument
{
    [InstrumentType(InstrumentType.String)]
    Lute,
    [InstrumentType(InstrumentType.String)]
    Guitar,
    [InstrumentType(InstrumentType.Wind)]
    Flute,
    [InstrumentType(InstrumentType.Percussion)]
    Drum
}

4)在一个独立的课程中?

public class ValidInstrument
{
public InstrumentType Type{get;set;}
public Instrument Instrument{get;set;}
}

具有静态运行时填充

哪种方法更好,或者如果依赖于哪种因素应该影响选择

3 个答案:

答案 0 :(得分:1)

因为[Flags]表示enum值可以存储为位,所以使用注释进行分组而不是单独的数据结构是平衡潜在可读性和潜在性能的一种方法......以及为什么使用{{ 1}}但出于性能原因?

答案 1 :(得分:1)

如果你只是想管理一个简单的关系,那么

Dictionary<Instrument, InstrumentType>

如果您需要严格执行继承

public class Guitar : StringInsturment 

我认为这可能有枚举层次结构,但我只是没有得到它解决的现实解决方案。所以吉他有一个字符串描述。当你用它包装一些代码来做它的事情时,你会更好地使用类继承。

答案 2 :(得分:1)

一旦你开始谈论事物之间的关系,感觉就像你在谈论继承。最佳做法是将其表示为类结构。

class Instrument
{
    void Play();
}

class StringedInstrument : Instrument
{
    void Strum();
}

class Guitar : StringedInstrument
{
}

使用工厂类/方法和一些其他设计模式,您应该能够处理相同的事情,并且枚举可以让您,还有更多您永远无法使用枚举处理。

如果你想找到所有演奏弦乐器的乐队成员,你可以简单地让所有成员在他们的乐器和#34;弦乐器。这应该可以通过Type.IsSubclassOf()调用在C#中完成。

如果开发人员随后创建了一个继承自Flute的{​​{1}}类,就像上面的评论一样,那么你应该解雇开发人员! :)如果您正在讨论将StringedInstrument对象分配给Flute实例,那么C#将阻止该对象,因为强制转换无效。您可以将StringedInstrument转换为FluteWindInstrument,但不得Instrument,除非开发人员错误地将其从错误的工具类型继承。