Контракт работает нормально, однако, если вы посмотрите на подпись метода first
, вы сможете понять, что происходит и почему найденный объект не применяется автоматически:
public inline fun <T> Iterable<T>.first(predicate: (T) -> Boolean): T
Тип возвращаемого значения метода first
такой же, как тот, который определен для всех элементов в экземпляре Iterable
, PictureEvent
в вашем случае, и никакое автокастирование внутри предиката, к сожалению, не может это изменить.
Вместо контрактов, например, вы можете сначала отфильтровать свой список по желаемому типу класса, а затем взять первый элемент:
val creationEvent = events
.filterIsInstance(PictureEvent.PictureCreated::class.java)
.first()
или создать собственное расширение, подобное на first
:
inline fun <reified R> Iterable<*>.firstOfInstance(): R {
val first = first { it is R }
return first as R
}
// or wrapping filterIsInstance
inline fun <reified R> Iterable<*>.firstOfInstance(): R {
return filterIsInstance(R::class.java).first()
}
val creationEvent = events.firstOfInstance<PictureEvent.PictureCreated>()