あなたのユース ケース (プロパティ エディター) では、最良の解決策は scala 2.10 で利用可能な scala リフレクションに依存することだと思います。クラスのTypeTag
を指定すると、そのすべてのメンバーとその値の完全な型 (消去なし) を取得し、そこからプロパティ エディターに入力できます。列挙型の場合は、 を使用TypeTag
して次の方法で値を取得します:
Scala 2.10 リフレクションを使用して、列挙型の値を一覧表示するにはどうすればよいですか?
さて、あなたは scala リフレクションを使いたくない、あるいは使えないかもしれません。それが本当なら、あなたはワームの缶全体を開いています:)
TL;DR:これは標準を使用して不可能であるEnumeration
ため、おそらく Ptharien's Flame's answer に示されているように列挙値を明示的にラップする必要がありますのフォークEnumeration
)。以下に、私のすべての試みについて詳しく説明します。ご容赦ください。
残念ながら、私には不明な理由で (シリアライゼーションの問題に関係していると思われますが)、そのインスタンスEnumeration.Value
を指すフィールドがありません。Enumeration
がどのように実装されているかを考えるとEnumeration
、これは簡単に実装できますが、もちろん、Enumeration を fork してバージョンを変更する以外には何も言えません (これは、まさにこの目的のために行ったものであり、さらにシリアライゼーションとリフレクションの適切なサポートを追加するために行ったものですが、掘り下げます)。
を変更できない場合は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
によってこれを回避できることに注意してください。実際には、カスタムの列挙型を使用する道を既に進んでいるので、そうしない理由はありません。判断はあなたに任せます)。
したがって、ここに別の見方があります:
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
アクセス時にのみ行われるためです。言い換えれば、呼び出し時に、コンパイラーは列挙型の正確な静的型を知る必要があります (コンパイラーは、赤の型がだけでなく であることを静的に認識している必要があります)。そして、あなたが言及したユースケース(プロパティエディター)では、列挙値のタイプを取得するためにJavaリフレクション(すでにスカラリフレクションを使用しないと想定しています)にのみ依存でき、Javaリフレクションは( extends ) のタイプとして。したがって、基本的にここで立ち往生しています。あなたの最善の策は、最初にscalaリフレクションを使用することです。red.enum
Colors
enum
Colors.Value
Enumeration# Value
Enumeration#Val
Enumeration#Value
Colors.Red