https://kotlinlang.org logo
Title
s

Shan

03/24/2019, 7:42 AM
Hey all, have a quick question: if I have a class which has a property whose type will always definitely be a certain type, is there a way I can specify that in my code so I don't have to do exhaustive when checks constantly? I tried using
as
but I couldn't get it to work, probably doing it wrong. My use-case:
c

Czar

03/24/2019, 7:45 AM
You could put
when
into an extension property, e.g.
deviceScope
. That way
when
will still be there but you won't have to repeat yourself.
s

Shan

03/24/2019, 7:48 AM
Thanks for the reply @Czar. I'm having a hard time visualizing your suggestion, could you provide a brief example perhaps?
c

Czar

03/24/2019, 8:02 AM
open class Scope

class DeviceScope(val name: String) : Scope()

open class Fragment {
    val scope: Scope = DeviceScope("Example device scope")
}

val Fragment.deviceScope: DeviceScope
    get() {
        check(scope is DeviceScope) {
            "Non-DeviceScope scopes are not allowed"
        }
        return scope
    }

class MyFragment : Fragment() {
    init {
        println(deviceScope.name)
    }
}
s

SiebelsTim

03/24/2019, 8:13 AM
scope as DeviceScope
should work as well. I don't know why it wouldn't work for you.
s

Shan

03/24/2019, 8:15 AM
Thank you for the example @Czar! @SiebelsTim I'm not sure, maybe I was doing something wrong when I tried it before. I'll try it again I suppose and see if that works
c

Czar

03/24/2019, 8:17 AM
class MyFragment : Fragment() {
    init {
        (scope as DeviceScope).name
    }
}
This works but is again repetitive. You could combine both to avoid it:
val Fragment.deviceScope: DeviceScope
    get() = scope as DeviceScope

class MyFragment : Fragment() {
    init {
        deviceScope.name
    }
}
I would leave my original one though with the
check(){}
, I think that makes the intent more obvious.
s

Shan

03/24/2019, 8:21 AM
Ah okay, I see what I was doing now before when I was trying to use
as
. I was setting it to a value
val deviceScope = scope as DeviceScope
which was throwing a NPE... for reasons I'm still not sure I understand. When I use it like
(scope as DeviceScope).name
it works fine. I will probably make extension functions for Fragment class though as that is quite handy.
Yup, the extension properties work great and are very clean. Thanks again!
🙂 1
h

Hamza

03/24/2019, 10:56 AM
Use sealed classes
l

LeoColman

03/24/2019, 4:09 PM
The issue with sealed classes is that you'd have to declare everything in the same file
Perhaps it gets somewhat ugly