HixField
HixField

Reputation: 3786

Get enum value based on it's ordinal in a generic class

Consider the below code:

class SegmentController<E : Enum<E>>() {

    fun getEnumForOrdinal(ordinal: Int) : E {
        //values is undefined?
        //how can I return the enum for the specified ordinal value?
        return E.values()[ordinal]
    }

    fun getOrdinalForEnum(enum: E): Int {
        //no problem getting the ordinal from the supplied E enum
        return enum.ordinal
    }

}

Its a generic class, taking any Enum as a template.

I did my research but cannot find any solution based on the ordinal, links I found:

Upvotes: 0

Views: 1215

Answers (1)

Marek
Marek

Reputation: 283

You could pass the enum's class as a constructor argument and access the enum values via enumConstants:

class SegmentController<E : Enum<E>>(private val clazz: Class<E>) {

    fun getEnumForOrdinal(ordinal: Int): E {
        return clazz.enumConstants[ordinal]
    }

    fun getOrdinalForEnum(e: Enum<E>): Int {
        return e.ordinal
    }
}

enum class SEGMENTS {A, B, C}

fun main() {
    val controller = SegmentController(SEGMENTS::class.java)
    println(controller.getOrdinalForEnum(SEGMENTS.B))
    println(controller.getEnumForOrdinal(1))
}

Alternatively, you could define getEnumForOrdinal as an inline function with a reified type parameter E and use enumValues to access the enum's values:

class SegmentController<E : Enum<E>>() {

    inline fun <reified E : Enum<E>> getEnumForOrdinal(ordinal: Int): E {
        return enumValues<E>()[ordinal]
    }

    fun getOrdinalForEnum(e: Enum<E>): Int {
        return e.ordinal
    }
}

enum class SEGMENTS {A, B, C}

fun main() {
    val controller = SegmentController<SEGMENTS>()
    println(controller.getOrdinalForEnum(SEGMENTS.B))
    println(controller.getEnumForOrdinal<SEGMENTS>(1))
}

See also: https://kotlinlang.org/docs/reference/enum-classes.html#working-with-enum-constants

A superb explanation of the reified keyword is given by this answer.

I would expect the E.values() to be available, but its not inside the generic class?

The values() method is not available in the Enum class.

Upvotes: 1

Related Questions