Я могу придумать три способа сделать то, что вы хотите, без изменения определения любого из классов.
Во-первых, классы типа :
object EventTypeClasses {
sealed trait Named[T] { def suiteName(t: T) String }
implicit object Succeeded extends Named[TestSucceed] {
def suiteName(t: TestSucceeded) = t.suitName
}
implicit object Failed extends Named[TestFailed] {
def suiteName(t: TestFailed) = t.suitName
}
}
...
import EventTypeClasses._
def getInfo[T <: Event : Named](event: T): Unit = {
implicitly[Named[T]].suitName(event)
}
}
Еще один способ - трюк "pimp my library":
object EventWithName {
sealed trait It { def suitName: String }
implicit class Succeeded(e: TestSucceeded) extends It { def suitName = e.suitName }
implicit class Failed(e: TestFailed) extends It { def suitName = e.suiteName }
}
...
def getInfo(event: EventWithName.It) = println(event.suiteName)
...
import EventWithName._
getInfo(new TestSucceeded(...))
Наконец, structural types
, При этом используется рефлексия, и, как правило, это вызывает недовольство, но если вы собираетесь использовать его только для тестирования, это, вероятно, хорошо:
type Named = { def suiteName: String }
def getInfo(event: Named) = println(event.suiteName)
Вы также можете просто использовать match-case, если это единственное место вам это нужно, чтобы оно не повторялось:
def getInfo(event: Event) = event match {
case e: TestSucceeded => println(e.suiteName)
case e: TestFailed => println(e.suiteName)
case _ => ???
}
Вы можете комбинировать это с вышеприведенной «сутенеркой», чтобы она выглядела лучше (чтобы вам не приходилось иметь дело с странный EventWithName.It
, и пользователям getInfo
не нужно импортировать последствия:
object EventWithName {
implicit class Pimped(val event: Event) extends AnyVal {
def suitName = event match {
case e: TestSucceeded => e.suiteName
case e: TestFailed => e.suiteName
case _ => ???
}
}
}
import EventWithName._
def getInfo(e: Event) = {
println(e.suiteName)
doOtherThingsWithEvent(e)
}
...
// No need to import implicits here
getInfo(new TestSucceeded(...))