How can I share sealed class methods by the subclasses and return the typeof "this"? I don't want to cast every time I call it, but implement it in the method signature if possible. Is there a simple way?
sealed class Base {
fun customCopy() = when (this) {
is X -> copy()
is Y -> copy()
}
}
data class X(val x: String) : Base()
data class Y(val y: String) : Base()
fun main() {
val x1 = X("x")
val x2: X = x1.customCopy() // Required X, but found Base
}
Above, I want x1.customCopy()
to return X
instead of Base
.
CodePudding user response:
You have to use generics to implement it.
Something like this:
fun <T: Base> customCopy():T = when (this) {
is X -> copy()
is Y -> copy()
} as T
Or you can use extension function which provides more type safety:
fun <T: Base> T.extCopy():T = when(this) {
is X -> copy()
is Y -> copy()
else -> throw InvalidParameterException()
} as T
CodePudding user response:
That doesn't really make any sense, might be more clear for you if you add the explicit return type of customCopy() instead of inferring it.
fun customCopy(): Base = when (this) {
is X -> copy()
is Y -> copy()
}
customCopy has to return Base, otherwise the second code path can't compile. If you remove all non-X returning code paths (eg. by throwing an exception) the inferred type will become X instead.
It's quite unclear what problem you are really asking to solve, because your example should just call x1.copy() directly.