¿Cómo escribir una transformación reutilizable para el valor de String to Enum en un grupo de classs Enum? (Kotlin)

Tengo un grupo> 5 de classs Enum que toman el parámetro String en sus valores, y quiero tener un código simple para todas estas classs Enum para convertir desde un campo String en el object JSON.

enum class Religiousness(val jsonStr: String, val resID: Int) { NotAtAll("none", R.string.not_religious), Somewhat("somewhat", R.string.somewhat_religious), Very("very", R.string.very_religious), ; override fun toString() = jsonStr fun displayString(res: Resources) = res.getString(resID) } 

Quiero ser capaz de escribir código como este

 fun JsonConvertStrToEnum(enumClass: Class<Enum<*>>, str: String): Enum<*> { for (enumval in enumClass.enumConstants) { if ((enumval as IJsonStringConvertible).jsonStr() == str) return enumval } throw IllegalArgumentException("Gave an invalid enum value for class ${enumClass.canonicalName}") } 

Me está costando averiguar si IJsonStringConvertible puede funcionar, y cuál sería su definición, y cómo implementarlo en las instancias de valores de Enum. ¿Algún consejo?

Actualización: ahora he escrito el convertidor como esto. Es esta la mejor manera? ¿Puedo express también que el valor de retorno es un subtipo del parámetro, por lo que no es necesario emitir el valor de retorno?

 fun JsonConvertStrToEnum(enumClass: Class<out Enum<*>>, str: String): Enum<*> { for (enumval in enumClass.enumConstants) { if (enumval.toString() == str) return enumval } throw IllegalArgumentException("Gave an invalid enum value for class ${enumClass.canonicalName}") } 

Los enums como otras classs pueden implementar interfaces como esta:

 interface IJsonStringConvertible { val jsonStr:String } enum class Religiousness(override val jsonStr: String, val resID: Int) : IJsonStringConvertible { NotAtAll("none", R.string.not_religious), Somewhat("somewhat", R.string.somewhat_religious), Very("very", R.string.very_religious), ; override fun toString() = jsonStr fun displayString(res: Resources) = res.getString(resID) } 

Que luego se usaría como:

 for (enumval in enumClass.enumConstants) { if ((enumval as IJsonStringConvertible).jsonStr == str) return enumval } 

Sin embargo, la búsqueda anterior puede ser costosa (si se usa millones de veces). Eche un vistazo a la pregunta de búsqueda inversa para descubrir cómo hacerlo de manera más eficiente.

Si ayuda a alguien, aquí está la versión final, creo que funciona tal vez 🙂

 fun <EnumT : Enum<EnumT>> ConvertStrToEnum(enumClass: Class<EnumT>, str: String?): EnumT? { if (str == null) return null for (enumval in enumClass.enumConstants) { if (enumval.toString() == str) return enumval } throw IllegalArgumentException("Gave an invalid enum value for class ${enumClass.canonicalName}") } fun <EnumT : Enum<EnumT> > ConvertStrArrayToEnumSet(enumClass: Class<EnumT>, array: List<String>?) : EnumSet<EnumT> { val set = EnumSet.noneOf(enumClass) array?.forEach { value -> set.add(ConvertStrToEnum(enumClass, value)) } return set } 
  • Invocando Acción por reference en Kotlin
  • Parámetros del tipo de context de Hadoop en Kotlin
  • Directorio de proyectos de reference desde cualquier lugar
  • Formato en templates de cadenas kotlin
  • No se pueden usar todos los parameters de configuration con una configuration personalizada en gradle con kotlin-dsl
  • JPA, Spring Data y Kotlin - Guardar loggings
  • La actualización automática de la versión de la biblioteca para proyectos Gradle no está soportada actualmente. Actualice su build.gradle manualmente
  • Error: Kotlin: no se permiten varios valores para la opción de complemento org.jetbrains.kotlin.kapt: salida
  • Kotlin: ¿Cómo puedo verificar si un número tiene puntos decimales (la solución del module no funciona)
  • Usando @ EnableNeo4jRepositories (basePackageClasses = "myApp") en Kotlin
  • Clase de datos kotlin + validation de frijol jsr 303