[c#] 通过继承扩展枚举


Answers

当内置的枚举不够用时,你可以用旧式的方式来创建自己的枚举。 例如,如果您想要添加其他属性(例如说明字段),则可以按如下所示进行操作:

public class Action {
    public string Name {get; private set;}
    public string Description {get; private set;}

    private Action(string name, string description) {
        Name = name;
        Description = description;
    }

    public static Action DoIt = new Action("Do it", "This does things");
    public static Action StopIt = new Action("Stop It", "This stops things");
}

然后你可以像这样像枚举一样对待它:

public void ProcessAction(Action a) {
    Console.WriteLine("Performing action: " + a.Name)
    if (a == Action.DoIt) {
       // ... and so on
    }
}

诀窍是确保构造函数是私有的(或者如果您想要继承,则受到保护),并且您的实例是静态的。

Question

我知道这与枚举的想法背道而驰,但是可以在C#/ Java中扩展枚举吗? 我的意思是在向枚举中增加新值的意义上“扩展”,而且在从现有枚举继承的OO意义上也是“扩展”。

我认为这在Java中是不可能的,因为它最近才得到它们(Java 5?)。 不过,C#似乎更能原谅那些想做疯狂事情的​​人,所以我认为这可能有些可能。 想必它可以通过反射来破解(而不是你实际上都会使用这种方法)?

我不一定有兴趣实施任何给定的方法,它只是当我想到它时引起了我的好奇心:-)




你不能继承/扩展一个枚举,你可以使用attributes声明一个描述 。 如果你正在寻找一个整数值,那是内置的。




如果你回到源代码和编辑中,添加枚举是一件很常见的事情,任何其他方式(如果可能的话)(继承或反射,如果可能的话)很可能会在你升级图书馆时出现并击中你,他们已经引入了相同的枚举名相同的枚举值 - 我已经看到很多低级代码,其中整数与二进制编码匹配,在那里你会遇到问题

理想情况下,代码引用枚举应该只写成等于(或开关),并且通过不期望枚举集为const




我希望能够将值添加到C#枚举中,这些枚举是现有值的组合。 例如(这是我想要做的):

AnchorStyles被定义为

public enum AnchorStyles { None = 0, Top = 1, Bottom = 2, Left = 4, Right = 8, }

我想添加一个AnchorStyles.BottomRight = Right + Bottom,而不是说

my_ctrl.Anchor = AnchorStyles.Right | AnchorStyles.Bottom;

我只能说

my_ctrl.Anchor = AnchorStyles.BottomRight;

这不会导致上面提到的任何问题,所以如果可能的话,它会很好。




如果你的意思是扩展到基类的意义上,那么在Java中没有。

但是,如果这就是你的意思,你可以扩展一个枚举值来拥有属性和方法。

例如,以下使用括号枚举:

class Person {
    enum Bracket {
        Low(0, 12000),
        Middle(12000, 60000),
        Upper(60000, 100000);

        private final int low;
        private final int high;
        Brackets(int low, int high) {
            this.low = low;
            this.high = high;
        }

        public int getLow() {
            return low;
        }

        public int getHigh() {
            return high;
        }

        public boolean isWithin(int value) {
           return value >= low && value <= high;
        }

        public String toString() {
            return "Bracket " + low + " to " + high;
        }
    }

    private Bracket bracket;
    private String name;

    public Person(String name, Bracket bracket) {
        this.bracket = bracket;
        this.name = name;
    }

    public String toString() {
        return name + " in " + bracket;
    }        
}



有时候,即使我想要做这样的事情,并发现枚举扩展会讲很多基本概念......(不仅仅是多态)

但是如果在外部库中声明了枚举,你仍然可能需要做,并且记住在使用这个枚举扩展时应该特别小心......

public enum MyEnum { A = 1, B = 2, C = 4 }

public const MyEnum D = (MyEnum)(8);
public const MyEnum E = (MyEnum)(16);

func1{
    MyEnum EnumValue = D;

    switch (EnumValue){
      case D:  break;
      case E:  break;
      case MyEnum.A:  break;
      case MyEnum.B:  break;
   }
}



枚举应该代表所有可能值的列举,所以扩展而不是违背这个想法。

然而,你可以在Java中做什么(大概是C ++ 0x)有一个接口,而不是一个枚举类。 然后将标准值放入实现该功能的枚举中。 显然你不会使用java.util.EnumSet之类的东西。 这是“更多NIO功能”中采用的方法,应该在JDK7中。

public interface Result {
    String name();
    String toString();
}
public enum StandardResults implements Result {
    TRUE, FALSE
}


public enum WTFResults implements Result {
    FILE_NOT_FOUND
}



Related



Tags

c# c#   java java   .net .net