2014-11-28 2 views
4

У меня есть объект, как:Список всех классов в объекте с помощью отражения

sealed trait Message 
object Message { 
    case class DoSomething(...) extends Message 
    case class DoSomethingElse(...) extends Message 
    ... 
} 

, что я пытаюсь сделать, это создать список всех сообщений в объекте Message.

То, что я до сих пор:

val messages: Iterable[Class[_ <: Message]] = { 
    import scala.reflect.runtime.universe._ 
    val mirror = runtimeMirror(this.getClass.getClassLoader).reflect(Message) 
    typeOf[Message.type].decls.collect { 
    case c: ClassSymbol if c.toType <:< typeOf[Message] => 
     mirror.reflectClass(c).symbol.getClass.asInstanceOf[Class[_ <: Message]] 
    } 
} 

Но это дает не очень информативное сообщение об ошибке для меня:

scala.ScalaReflectionException: класс DoSomething статический класс, используйте reflectClass на RuntimeMirror чтобы получить его ClassMirror

насколько я вижу, я использую reflectClass на RuntimeMirror. Я что-то упускаю? Thanks

+0

Только предположение: может быть, 'toType' вызывает то, и вам нужно сделать' c.reflectClass.toType <: lmm

+0

Ах, мое плохое. Я забыл упомянуть, что я получил ошибку здесь 'mirror.reflectClass (c)', поэтому я думаю, что это не проблема 'toType'. – gysyky

ответ

6

После того, как вы больше читали о отражениях Скала, будучи богаче знаниями, я нашел решение. Все, что мне было нужно:

val messages = { 
    import scala.reflect.runtime.universe._ 
    val mirror = runtimeMirror(this.getClass.getClassLoader) 
    typeOf[Message.type].decls.collect { 
    case c: ClassSymbol if c.toType <:< typeOf[Message] => 
     mirror.runtimeClass(c).asInstanceOf[Class[_ <: Message]] 
    } 
} 
+0

+1 для обеспечения ответа на себя и не оставлять этот вопрос без ответа, и кстати мне тоже полезно. – giampaolo