https://kotlinlang.org logo
#getting-started
Title
# getting-started
m

Michael de Kaste

11/01/2021, 11:24 AM
Is there a way to to associate an enum with a sealed class implementation? Lets say you have a generic enum accessible in your entire project (in my case I'm working with types of mental health care) and throughout your project, sometimes, per type, we need a slightly different implementation. Currently I have an Enum with Type1, Type2 and Type3, and then a sealed class with an implementation for every type. Now I have a map, in which I would like to give a key (enum) and then get back the specific implementation. However, I cannot guarantee that if you call the enummap with type1 key you get a value that represented type1 value
j

Joffrey

11/01/2021, 11:29 AM
There is no language feature associating the values of an enum type to subtypes of a sealed class. But it's possible to do this yourself depending on what you need. You can for instance store the corresponding enum value as a property of the sealed class so you can find the instance with that value. This would allow you to build your map automatically. If you want the kind of type safety you described, I wonder how you would use it in real life? I mean, if the enum value is known in advance (
yourMap.get(YourEnum.TYPE_1)
) then you could just build a correct instance of the sealed class's subclass right away instead. However, if you're using a dynamic enum value (
yourMap.get(someEnumValueVariable)
), you can't know at compile time which type of instance you will get anyway, so there is no real point in enforcing that your map returns the specific subtype anyway. Or did I miss something here?
If you really really want this type safety, you could use another sealed class instead of the enum, with only `object`s as subtypes. That sealed class would be generic and the type parameter would be the type of your original sealed class that you want this new one to represent:
Copy code
sealed class Original {
    data class ActualImpl1(...) : Original()
    data class ActualImpl2(...) : Original()
}

// this replaces your enum
sealed class MyKey<T : Original> {
    object Type1 : MyKey<ActualImpl1>()
    object Type2 : MyKey<ActualImpl2>()
}
This would allow you to build your heterogeneous typesafe map, but at this point I believe it might be better to use the original sealed class instead of the enum in more places 😄
m

Michael de Kaste

11/01/2021, 11:39 AM
the values are not objects sadly. Per person/worker/registration/etc, per domain, you can have a different version of an implementation meaning that the values of said map are data classes, that are filled upon creation. Currently, what we are doing is just having all these classes that have the per domain information as loose vals in a class like so:
class Workflow{
val someData: String
val someMoreData: String
val type1Information: Information.Type1? = null
val type2Information: Information.Type2? = null
val type3Information: Information.Type3? = null
}
and then on creation we fill the known and desired information and can easily just access all the vals. the problem is that the amount of types in our application is slowly growing as we are implementing more and more for our customers and therefor, having littered values is bloating our code. An EnumMap would provide the perfect solution I would think
and at other times we have 2 classes with information for these types and we would like to know what the other class has for type1 for instance in order to request the specific values from these class. Now it all needs to be done manually; if I have these 2 sealed class informations and now on another spot, for every type, I need to request the data from these classes, I need to do all kinds of manual checks in order to get the correct information. If you get what I mean
j

Joffrey

11/01/2021, 2:16 PM
the values are not objects sadly. Per person/worker/registration/etc, per domain, you can have a different version of an implementation meaning that the values of said map are data classes, that are filled upon creation.
The `object`s in my suggestion were meant to replace the enum, not the current sealed class hierarchy that you have. The
Original
sealed class in my example would still be there and still have proper classes with data inside. The idea of the second sealed class instead of the enum was to allow a type safe map access you seemed to want.
3 Views