igor.wojda
08/04/2023, 7:10 AM.customFilterReified<AdvancedInterface>()
and return a list of Advanced
objects instead of BaseInterface
objects (heaving same behaviour as filtering using KClass
.customFilterWithKClass(AdvancedInterface::class)
) ? 🤔
interface BaseInterface
interface AdvancedInterface
class Advanced : BaseInterface, AdvancedInterface {
val someProperty = "someProperty"
}
// 1 FILTER USING KCLASS - OK
fun <T : BaseInterface> List<T>.customFilterWithKClass(item: KClass<*>): List<T> = filter { item.isInstance(it) }
// 2 FILTER USING REIFIED - PROBLEM
inline fun <reified T> List<BaseInterface>.customFilterReified(): List<BaseInterface> = filter { it is T }
// USAGE
fun main() {
val items = listOf(Advanced())
// 1 FILTER USING KCLASS - OK
items // List<Advanced>
.customFilterWithKClass(AdvancedInterface::class) // returns List<Advanced> - OK
.map { it.someProperty } //
// 2 FILTER USING REIFIED - PROBLEM
items // List<Advanced>
.customFilterReified<AdvancedInterface>() // returns List<BaseInterface> - PROBLEM
.map { it.someProperty } // ERROR: Unresolved reference: someProperty
}
Wout Werkman
08/04/2023, 7:26 AMinline fun <reified T> List<BaseInterface>.customFilterReified(): List<T /* Not BaseInterface */> = …
I’m quite sure that what you want is items.filterIsInstance<AdvancedInterface>()
Wout Werkman
08/04/2023, 7:28 AMigor.wojda
08/04/2023, 10:13 AMcustomFilterReified
gives me AdvancedInterface
type rather than Advanced
type. Is there a way to get the oriiginal receiver type within the extension (Advanced
) 🤔
interface BaseInterface
interface AdvancedInterface
class Advanced : BaseInterface, AdvancedInterface {
val someProperty = "someProperty"
}
// 1 FILTER USING KCLASS - OK
fun <T : BaseInterface> List<T>.customFilterWithKClass(item: KClass<*>): List<T> = filter { item.isInstance(it) }
// 2 FILTER USING REIFIED - PROBLEM
inline fun <reified T> List<BaseInterface>.customFilterReified(): List<T> = filterIsInstance<T>()
// USAGE
fun main() {
val items = listOf(Advanced())
// 1 FILTER USING KCLASS - OK
items // List<Advanced>
.customFilterWithKClass(AdvancedInterface::class) // returns List<Advanced> - OK
.map { it.someProperty } //
// 2 FILTER USING REIFIED - PROBLEM
items // List<Advanced>
.customFilterReified<AdvancedInterface>() // returns List<AdvancedInterface> - PROBLEM
.map { it.someProperty } // ERROR: Unresolved reference: someProperty
}Wout Werkman
08/04/2023, 10:24 AMcustomFilterWithKClass
. It should be KClass<T>
. Currently it just infers T
from the receiver list. So the only reason // 1
works is because val items
is already of type Advanced
.
There is no realistic use case to call List<A>.filterIsInstance<B>()
given that B
is a supertype of A
. And your compiler output is exactly as you should expect