Hello,
I have encountered a problem with generics. I’m trying to use a library which can trigger handler for a specific event. There is a HandlerRegistry#registerHandler
to bind event classes to handlers:
import kotlin.reflect.KClass
// ===============================================================
// Code out of my control (library)
// ===============================================================
interface Event
class EventWrapper<T : Event>
interface Handler<T : Event> {
fun handle(eventWrapper: EventWrapper<T>)
}
class HandlerRegistry {
fun <T : Event> reigsterHandler(type: KClass<T>, handler: Handler<T>) {}
}
I have defined an event and its handler. Also I have created HandlerDefinition
class which implements Handler
interface and introduce additional type
field:
class FirstEvent : Event
abstract class HandlerDefinition<T : Event>(val type: KClass<T>) : Handler<T>
class FirstEventHandler : HandlerDefinition<FirstEvent>(FirstEvent::class) {
override fun handle(eventWrapper: EventWrapper<FirstEvent>) = Unit
}
Now to the point. HandlerDefinition
allows me to build a list of all handlers and register them by iterating over that list with forEach
. Problem occurs when I’m trying to invoke registerHandler
method:
val handlerRegistry = HandlerRegistry()
val eventHandlers: List<HandlerDefinition<out Event>> = listOf(
FirstEventHandler()
)
// Compiler error - type of the value passed as second parameter is incorrect
eventHandlers.forEach { handler -> handlerRegistry.reigsterHandler(handler.type, handler) }
// Works fine
handlerRegistry.reigsterHandler(FirstEvent::class, FirstEventHandler())
Compiler shows following error:
Type mismatch: inferred type is Scratch_5.Event but CapturedType(out Event) was expected
I’m pretty confused. handler
variable passed as second parameter is an instance of HandlerDefinition
which implements Handler
interface so it is correct. What could be the cause of this error? I would greatly appreciate any suggestions.