You can solve your problem by encapsulating getIntent
in a generic class with a private constructor and providing its instances parameterized with acceptable types:
class IntentFactory<in T> private constructor() {
companion object {
val int = IntentFactory<Int>()
val long = IntentFactory<Long>()
val string = IntentFactory<String>()
}
fun getIntent(
context: Context,
clazz: Class<*>,
command: Command,
map: Map<String, T>?
): Intent {
// your implementation
}
}
Use case:
IntentFactory.int.getIntent(
context,
clazz,
command,
mapOf("1" to 1)
)
UPD:
If you mean that map can contain Int
, Long
and String
values simultaneously, you should create a class that wraps objects of these types. I also suggest adding key
property to this class:
class IntentExtra<out T> private constructor(val key: String, val value: T) {
companion object {
operator fun invoke(key: String, value: Int) = IntentExtra(key, value)
operator fun invoke(key: String, value: Long) = IntentExtra(key, value)
operator fun invoke(key: String, value: String) = IntentExtra(key, value)
}
}
Now your function may accept List<IntentExtra<*>>
:
fun getIntent(
context: Context,
clazz: Class<*>,
command: Command,
extra: List<IntentExtra<*>>?
): Intent {
// your implementation
}
Use case:
IntentFactory.getIntent(
context,
clazz,
command,
listOf(
IntentExtra("int", 1),
IntentExtra("long", 1L),
IntentExtra("string", "s")
)
)
You can also create a DSL to make client code a little bit cleaner:
class IntentExtraDSL(private val intent: Intent) {
private fun extra(key: String, value: Any) {
intent.putExtra(key, value)
}
infix fun String.extra(value: Int) = extra(this, value)
infix fun String.extra(value: Long) = extra(this, value)
infix fun String.extra(value: String) = extra(this, value)
}
fun getIntent(
context: Context,
clazz: Class<*>,
command: Command,
extra: IntentExtraDSL.() -> Unit
): Intent {
val intent = Intent(context, clazz)
intent.putExtra(KEY_COMMAND, command)
IntentExtraDSL(intent).extra()
return intent
}
Use case:
IntentFactory.getIntent(
context,
clazz,
command
) {
"int" extra 1
"long" extra 1L
"string" extra "s"
}