dave08
12/08/2021, 12:26 PM@ExperimentalStdlibApi
inline operator fun <reified T : Any> SharedPreferences.getValue(owner: Any?, property: KProperty<*>): T {
return when (val type = typeOf<T>()) {
is Set<*> ->
getStringSet(property.name.replace('_', '.'), emptySet()) ?: emptySet()
else -> error("Invalid type")
} as T
}
Joffrey
12/08/2021, 12:30 PMdave08
12/08/2021, 12:31 PMtypeOf<T>()
is a KType
whereas is
I think only works with actual instances...someobjinstance is Set<*>
Joffrey
12/08/2021, 12:32 PMdave08
12/08/2021, 12:39 PMJoffrey
12/08/2021, 12:42 PMval x by stringPreference()
and val x by stringSetPreference()
when (val type = typeOf<T>()) {
typeOf<Set<String>>() -> TODO()
else -> TODO()
}
But I'm not sure this is reliable.dave08
12/08/2021, 12:54 PMstringSetPreference(prefs)
... not as nice though?
What do you mean by exact matches? And why shouldn't it be reliable? I really only have those 3 types...import kotlin.reflect.typeOf
inline fun <reified T : Any> c() = when(val type = typeOf<T>()) {
typeOf<String>() -> 1
typeOf<Int>() -> 2
typeOf<Set<String>>() -> 3
typeOf<Set<Int>>() -> 4
else -> error("something else: ${type::class}")
}
val num: Any = 0
fun main() {
println(c<String>())
println(c<Int>())
println(c<Set<String>>())
println(c<Set<Int>>())
}
// Gives:
// 1
// 2
// 3
// 4
@ExperimentalStdlibApi
inline operator fun <reified T : Any> SharedPreferences.getValue(owner: Any?, property: KProperty<*>): T {
val keyName = property.name.replace('_', '.')
return when (typeOf<T>()) {
typeOf<Set<String>>() ->
getStringSet(keyName, emptySet<String>()) ?: emptySet<String>()
typeOf<String>() ->
getString(keyName, "")
else -> error("Invalid type")
} as T
}
Joffrey
12/08/2021, 1:25 PMWhat do you mean by exact matches?
I meant no supertypes are allowed for
T
with this approach, so for instance a CharSequence
property won't match the String
case. But for your use case it might be enough.
And why shouldn't it be reliable?
This is just a disclaimer because I have not looked at how
KType
's equality works. It may work perfectly fine, I just haven't checkedit has a receiver of SharedPreferences... since I have a few possible implementations of SharedPreferences... so it would beAh I see, so you want to simply delegate to... not as nice though?stringSetPreference(prefs)
prefs
like Map
does. Makes sense.
You could also design it to work with the syntax by prefs.string()
/ by prefs.stringSet()
etc.dave08
12/08/2021, 1:35 PMtypeOf()
returns a TypeReference
and has:
override fun equals(other: Any?): Boolean =
other is TypeReference &&
classifier == other.classifier && arguments == other.arguments && isMarkedNullable == other.isMarkedNullable
Raymond
12/08/2021, 7:28 PM