ZeMoon
ZeMoon

Reputation: 20274

Static properties from Generic parameters in Kotlin

Question:

  1. How can I reify object types when specified as a Generic Parameter
  2. Or, How can I implement Static properties in Kotlin?

I know the closest thing we have to static data is using object.

Simple Example

Having an interface which will only be implemented by Objects

interface SomeObject {
    val someProperty: String
}

object AnObject: SomeObject {
    override val someProperty = "someValue"
}

And using the interface as a generic constraint, I would like to be able to access these properties statically.

class GenericClass<O: SomeObject> { 

    var someValue: String
        get() = O.someProperty   // This is not possible
}

GenericClass<AnObject>().someValue

The only way would be to also pass the object as a constructor parameter

class GenericClass<O: SomeObject>(
    val obj: O
) { 
    var someValue: String
        get() = obj.someProperty
}

GenericClass(AnObject).someValue

Repeating the question above

  1. Is there a way to reify this object?
  2. Or, is there any other way to implement static properties on Types?

Upvotes: 1

Views: 183

Answers (1)

ZeMoon
ZeMoon

Reputation: 20274

One way to reify the object is using reflection:

inline fun <reified T> getObject(): T? = T::class.objectInstance

If you are really sure the generic type will be an object

inline fun <reified T> getObject(): T = T::class.objectInstance ?: error("Not an object!")

This can be used within a mock constructor for GenericClass

class GenericClass private constructor(private val obj: O) {

    var someValue: String
        get() = obj.someProperty

    companion object {
        inline operator fun <reified T: SomeObject> invoke(): GenericClass<T> = 
            GenericClass(T::class.objectInstance ?: error("unsupported type"))
    }
}

And can be called as desired using only a generic parameter

GenericClass<AnObject>().someValue

Upvotes: 0

Related Questions