Hi! I'm not sure of which channel is best for this...
# getting-started
m
Hi! I'm not sure of which channel is best for this, but I'm trying to get
provideDelegate
to work with generic output types. Basically, what I'm trying to do is the following setup:
Copy code
class Producer {
    inline fun <reified T> create(): ReadOnlyProperty<Any, T> {
        println("Creating a property with create(), return type is ${T::class}")
        TODO()
    }
    
    inline operator fun <reified T> provideDelegate(thisRef: Any, prop: KProperty<*>): ReadOnlyProperty<Any, T> {
        println("Creating a property with provideDelegate, return type is ${T::class}")
        TODO()
    }
}

class MyClass(producer: Producer) {
    val one: String by producer.create()
    //val two: String by producer
}
While the
val one
works perfectly fine, if I uncomment
val two
, it no longer compiles. Is there any way to do this? Kotlin Playground link: https://pl.kotl.in/vXOAoeauS Compilation fails with:
Copy code
Property delegate must have a 'provideDelegate(MyClass, KProperty<*>)' method. None of the following functions is suitable: public final inline operator fun <reified T> provideDelegate(thisRef: Any, prop: KProperty<*>): ReadOnlyProperty<Any, ???> defined in Producer
y
Looks the same as KT-17440. Only workaround seems to be using a method. If you need access to the
KProperty
inside create, then make create return a
PropertyDelegateProvider
instead like so:
Copy code
import kotlin.reflect.*
import kotlin.properties.*

class Producer {
    inline fun <reified T> create(): PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, T>>  = PropertyDelegateProvider { _, prop ->
        println("Creating a property with provideDelegate, return type is ${T::class}")
        TODO()
    }
}

class MyClass(producer: Producer) {
    val one: String by producer.create()
    val two: String by producer.create()
}

fun main() {
    val obj = MyClass(Producer()) // will fail immediately because of the TODO()s, that's normal
}