matt_dziubek
07/24/2017, 8:27 AMinterface RecyclerItem<in T : RecyclerView.ViewHolder> {
fun onBindViewHolder(holder: T?)
}
Generic is defined as in
because clearly RecyclerItem
is a consumer, hence I can only assign this instance to its subtype.
I also have a below implementations of `RecyclerItem`:
class ItemSuncalcData() : RecyclerItem<ItemSuncalcData.ViewHolder>
and:
class SomeOtherItem() : RecyclerItem<SomeOtherItem.ViewHolder>
Long story short I want to store above two instances in a List<RecyclerItem<RecyclerView.ViewHolder>>
, but because of in T
I can’t assign subclasses to its supertypes. What’s my best move here? I’ve written same code in java and only got unchecked cast warning.
The only way I could think of was to remove generics from the interface:
interface RecyclerItem {
fun onBindViewHolder(holder: RecyclerView.ViewHolder?)
}
But before I’ll change 15+ files (because of casting I would have to make) I wanted to ask you first, thanks in advance 😉
Take a look at this github repo I made showcasing my problem above: https://github.com/matdziu/GenericsKotlin. You can switch between two commits - one that uses generic way (compilation error in MainActivity) and the second which is the solution I think I found. Note that on production we’re using multiple different item types and factory pattern to choose a proper view holder (this sample is just a huge simplification).mzgreen
07/24/2017, 8:35 AMList<RecyclerItem<*>>
?matt_dziubek
07/24/2017, 8:50 AMmatt_dziubek
07/24/2017, 8:50 AMmzgreen
07/24/2017, 9:13 AMclass RecyclerView{
interface ViewHolder
}
interface RecyclerItem<in T : RecyclerView.ViewHolder> {
fun onBindViewHolder(holder: T?)
}
class ItemTextView : RecyclerItem<ItemTextView.ViewHolder> {
override fun onBindViewHolder(holder: ViewHolder?) {}
class ViewHolder : RecyclerView.ViewHolder {}
}
fun main(args: Array<String>) {
val list = mutableListOf<RecyclerItem<*>>()
list.add(ItemTextView())
println(list.size) // prints 1
}