如何创建两级枚举

时间:2013-09-20 07:04:59

标签: c# .net oop enums

很抱歉,如果问题的标题令人困惑,但我不知道怎么问。 真正想要的是拥有永不改变的只读数据。

目前我有两个枚举MeterTypeSubMeterType

public enum MeterType
{
  Water = 1001,
  Electricity = 1004,
  Gas = 1007
}

public enum SubMeterType
{
  DrinkingWater = 1002,
  UsageWater = 1003,
  SubsidiseGas = 1008,
  NonSusbsidisedGas = 1009
} 

现在我想使用以下这些

获取MeterType

string meterType = MeterType.Water.ToString("d");

并获得SubMeterType,是否可能有像

这样的东西
string subMeterType = MeterType.Water.DrinkingWater("d");

应该使用具有readonly属性的类的另一种方法吗? 或修改这些枚举以满足我的要求。

3 个答案:

答案 0 :(得分:7)

您可以在嵌套类中使用常量整数,而不是使用枚举:

public static class MeterType
{
    public const int Water = 1001;
    public const int Electricity = 1004;
    public const int Gas = 1007;

    public static class Waters
    {
        public const int DrinkingWater = 1002;
        public const int UsageWater = 1003;
    }

    public static class Gases
    {
        public const int SubsidiseGas = 1008;
        public const int NonSusbsidisedGas = 1009;
    }
}

答案 1 :(得分:3)

只需使用嵌套枚举:

public class MeterType
{
    public enum Water { }
}

但在这种情况下,您无法直接使用MeterType.Water,默认情况下这是不可能的。然后尝试使用嵌套对象或MeterType的辅助枚举。

public enum MeterType { }
public enum MeterTypeWater { }

在这种情况下,您需要为每个枚举使用不同名称的属性。最佳解决方案是不使用嵌套类:

public class MeterType
{
    public static WaterType Water { get; }
}

public class WaterType
{
    public readonly SubWaterType DrinkingWater = SubWaterType.DrinkingWater;
}

答案 2 :(得分:3)

您无法嵌套enum,但您已经知道了。您可以做的是拥有映射到您想要的各种类型的constreadonly属性/字段。然后在每种类型中,为子类型定义字段/属性。

public static class MeterTypes
{
    public static readonly Electricity electricity;
    public static readonly Gas gas;
    public static readonly Water water;

    static MeterTypes()
    {
        // initialize the meter types to their default
        MeterTypes.Water = Water.GenericWater;
        MeterTypes.Gas = Gas.GenericGas;
        MeterTypes.Electricity = Electricity.GenericElectricity;
    }

    private MeterTypes()
    {
        // private initialization prevents others from creating the class            
    }

    public class Electricity
    {
        public enum Type
        {
            Generic = 1007,
            SubsidisedElectricity = 1008,
            NonSubsidisedElectricity = 1009
        }

        public static readonly Electricity GenericElectricity;
        public static readonly Electricity SubsidisedElectricity;
        public static readonly Electricity NonSubsidisedElectricity;
        private Type ElectricityType;

        static Electricity()
        {
            SubsidisedElectricity = new Electricity(Type.SubsidisedElectricity);
            NonSubsidisedElectricity = new Electricity(Type.NonSubsidisedElectricity);
            GenericElectricity = new Electricity(Type.Generic);
        }

        // private constructor prevents creation from outside the class
        private Electricity(Type ElectricityType)
        {
            this.ElectricityType = ElectricityType;
        }

        public override string ToString()
        {
            return ElectricityType.ToString();
        }

        public string ToString(string format)
        {
            return ElectricityType.ToString(format);
        }
    }

    public class Gas
    {
        public enum Type
        {
            Generic = 1007,
            SubsidisedGas = 1008,
            NonSubsidisedGas = 1009
        }

        public static readonly Gas GenericGas;
        public static readonly Gas SubsidisedGas;
        public static readonly Gas NonSubsidisedGas;
        private Type gasType;

        static Gas()
        {
            SubsidisedGas = new Gas(Type.SubsidisedGas);
            NonSubsidisedGas = new Gas(Type.NonSubsidisedGas);
            GenericGas = new Gas(Type.Generic);
        }

        // private constructor prevents creation from outside the class
        private Gas(Type gasType)
        {
            this.gasType = gasType;
        }

        public override string ToString()
        {
            return gasType.ToString();
        }

        public string ToString(string format)
        {
            return gasType.ToString(format);
        }
    }

    public class Water
    {
        public enum Type
        {
            Generic = 1001,
            DrinkingWater = 1002,
            UsageWater = 1003
        }

        public static readonly Water GenericWater;
        public static readonly Water DrinkingWater;
        public static readonly Water UsageWater;
        private Type waterType;

        static Water()
        {
            DrinkingWater = new Water(Type.DrinkingWater);
            UsageWater = new Water(Type.UsageWater);
            GenericWater = new Water(Type.Generic);
        }

        // private constructor prevents creation from outside the class
        private Water(Type waterType)
        {
            this.waterType = waterType;
        }

        public override string ToString()
        {
            return waterType.ToString();
        }

        public string ToString(string format)
        {
            return waterType.ToString(format);
        }
    }
}

这可以这样使用

var w = MeterTypes.water; // will give generic water
var uw = MeterTypes.Water.UsageWater // will give usage water

您还可以使用Enum.ToString()方法。

您必须注意,此实现依赖于C#的区分大小写。这使得MeterTypes.electricityMeterTypes.Electricity分别引用字段和类。如果它以不区分大小写的语言(例如VB.NET)使用,则此代码很可能会失败。您可以通过为MeterTypes类中的静态字段使用其他名称(例如_Electricity而不是electricity)来避免这种情况。