分组枚举最佳做法

本文关键字:最佳 枚举 | 更新日期: 2023-09-27 17:55:43

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

[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;}
}

使用静态运行时填充

这些方法中哪一种更好,或者如果取决于情况,哪些因素应该影响选择

分组枚举最佳做法

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

class Instrument
{
    void Play();
}
class StringedInstrument : Instrument
{
    void Strum();
}
class Guitar : StringedInstrument
{
}

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

如果你想找到所有演奏弦乐器的乐队成员,你只需得到所有成员的乐器"是"弦乐器。这应该可以通过 C# 中的Type.IsSubclassOf()调用来完成。

如果开发人员随后创建了一个继承自StringedInstrumentFlute类,如您上面的评论所示,您应该解雇该开发人员! :)如果正在谈论将Flute对象分配给StringedInstrument实例,则 C# 会阻止此操作,因为强制转换无效。您可以将Flute转换为 WindInstrumentInstrument ,但除非开发人员错误地将其从错误的仪器类型继承,否则永远不要StringedInstrument

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

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

Dictionary<Instrument, InstrumentType>

如果你需要严格执行,那么继承

public class Guitar : StringInsturment 

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