我知道这反对了枚举的想法,但是有可能在C#/ Java中扩展枚举吗?我的意思是"扩展",无论是为枚举添加新值,还是从现有枚举继承的OO意义.
我认为它在Java中是不可能的,因为它最近才得到它们(Java 5?).C#似乎对想要做疯狂事情的人更宽容,所以我认为这可能是某种方式.据推测它可以通过反射来破解(不是你每次都使用那种方法)?
我不一定对实现任何给定的方法感兴趣,它只是在我遇到它时激起了我的好奇心:-)
你无法扩展枚举的原因是因为它会导致多态性问题.
假设您有一个包含值A,B和C的枚举MyEnum,并将其值D扩展为MyExtEnum.
假设某个方法需要myEnum值,例如作为参数.提供MyExtEnum值应该是合法的,因为它是一个子类型,但是现在当它结果是D时你要做什么呢?
要消除此问题,扩展枚举是非法的
当内置枚举不够时,你可以用旧时尚的方式来制作你自己的.例如,如果要添加其他属性(例如,描述字段),则可以按如下方式执行:
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 } }
诀窍是确保构造函数是私有的(如果你想继承,则保护),并且你的实例是静态的.
你的方法是错误的:枚举的子类会有更少的条目.
在伪代码中,想一想:
enum Animal { Mosquito, Dog, Cat }; enum Mammal : Animal { Dog, Cat }; // (not valid C#)
任何可以接受动物的方法应该能够接受哺乳动物,但不能相反.子类化是为了使某些更具体,而不是更一般.这就是为什么"对象"是类层次结构的根.同样,如果枚举是可继承的,那么枚举层次结构的假设根将具有所有可能的符号.
但不,C#/ Java不允许子枚举,AFAICT,尽管它有时会非常有用.这可能是因为他们选择将Enums实现为int(如C)而不是实体符号(如Lisp).(上面,(动物)1代表什么,(哺乳动物)1代表什么,它们是相同的值?)
不过,您可以编写自己的类似枚举的类(使用不同的名称).使用C#属性,它甚至可能看起来很好.
枚举应该代表所有可能值的枚举,因此扩展反而违背了这个想法.
但是,你可以用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 }