我想创建一个保存了枚举值的一般类,并允许访问枚举的可能值。 想想例如属性编辑器 - 你需要知道属性的当前价值,还需要能够了解其他值是合法的财产。 与枚举类型不应该事先知道,你应该能够与任何一种枚举的工作。
我首先想到的是这样的:
class EnumerationProperty[T <: Enumeration](value:T)
然而,这并不因为工作的枚举T是不是一个类型,它是一个对象。 我曾尝试其他的变化是:
class EnumerationProperty[T <: Enumeration](value:T.Value)
class EnumerationProperty[T <: Enumeration.Value](value:T)
(我不会去的,为什么这些不工作,因为我怀疑的原因是不是有趣的细节。)
在你的使用情况(属性编辑器)我认为最好的办法是依靠在斯卡拉2.10可用阶反射。 给定一个类的TypeTag
,你可以得到所有成员以及他们的价值观的全面型(不擦除),并从填充您的属性编辑器。 对于枚举,使用TypeTag
使用下面的方法来获得它们的值: 使用Scala的2.10思考如何列出枚举值?
现在,也许你不想或者不能使用Scala的反思,并从现在起,我会想是这样。 如果这是真的,那么你正在打开蠕虫:) TL的整体能; DR:这是不可能的使用标准的Enumeration
,所以你可能要explcitly包裹枚举值,如图Ptharien的火焰的答案(或滚你自主叉Enumeration
)。 下面我详细的我所有的努力,请多多包涵。
不幸的是,对于一些未知的原因,我(虽然我怀疑它与序列化问题做), Enumeration.Value
没有现场指向其Enumeration
的实例。 考虑到如何Enumeration
实现,这将是微不足道的实施,当然wehave没有发言权的,短分叉枚举和修改我们的版本(这实际上是我做了这个目的,再加上添加了序列化和反射适当的支持-但我diggress)。
如果我们不能修改Enumeration
,也许我们就可以延期吗? 纵观再次实施,这样的事情似乎工作:
class EnumerationEx extends Enumeration {
protected class ValEx(i: Int, name: String) extends Val(i, name) {
@transient val enum: Enumeration = EnumerationEx.this
}
override protected def Value(i: Int, name: String): Value = new ValEx(i, name)
}
object Colors extends EnumerationEx {
val Red, Green, Blue = Value
}
不利的一面是,这仅适用于枚举明确延长EnumerationEx
而不是Enumeration
,但它会比没有好。
不幸的是,这并不编译,只是因为def Value ...
被声明为final的Enumeration
所以没有方法来覆盖它。 (再次注意,分叉Enumeration
将允许circunvent这一点。其实,为什么不这样做,因为我们已经下使用自定义枚举anwyay的道路。我会告诉你判断)。
因此,这里是它的另一个看法:
class EnumerationEx extends Enumeration {
class ValueWithEnum( inner: Value ) {
@transient val enum: Enumeration = EnumerationEx.this
}
implicit def valueToValue( value: Value ): ValueWithEnum = new ValueWithEnum( value )
}
而事实上它按预期工作 。 或者看起来是这样。
scala> object Colors extends EnumerationEx {
| val Red, Green, Blue = Value
| }
defined module Colors
scala> val red = Colors.Red
red: Colors.Value = Red
scala> red.enum.values
res58: Enumeration#ValueSet = Colors.ValueSet(Red, Green, Blue)
万岁? 哦,不,因为从转换Value
,以ValueWithEnum
访问时,只是做red.enum
,而不是在实例化时Colors
枚举。 换句话说,当调用enum
编译器需要知道确切的静态类型枚举(编译器必须静态知道,红色的类型是Colors.Value
,而不是仅仅Enumeration# Value
)。 而在使用情况,你提到(属性编辑器),你只能依靠于Java反射(我已经假设你不会使用Scala的反射)来获取枚举值的类型,以及Java反射只会给你Enumeration#Val
(其延伸Enumeration#Value
)作为类型Colors.Red
。 所以基本上你被困在这儿了。 最好的办法是definitly使用Scala的反射摆在首位。
对于你的问题的第一部分。 你也可以为这个通用枚举值定义持有者:
case class EnumerationProperty[T <: Enumeration#Value](value:T)
但我不知道怎么弄不明确所有枚举值通过枚举对象。 枚举有values()
方法来获取所有值。 和计数#值链接枚举,但私下接触
class EnumProps[E <: Enumeration](val e: E)(init: e.Value) {...}
然后你可以使用e
和e.Value
实现类。