Kotlin - 如果对象的名称存储在字符串中,则访问 class 的对象

Kotlin - Accessing Objects of class if the name of Object is stored in a String

我有一个 class,它有多个伴随对象,它们是字符串列表。 在另一个 class (Activity) 中,我有一个字符串,它可以包含任何伴随对象的名称。有没有一种方法可以在没有 If/Else 语句的情况下访问其他 class 的伴随对象。

数据列表

class ProjectDataLists {
    companion object {
        var Countries: List<String> = listOf(
          "USA",
          "Canada",
          "Australia",
          "UK"
        )

        var Cars: List<String> = listOf(
          "Toyota",
          "Suzuki",
          "Honda",
          "Ford"
        )
    }
}

Activity Class

var IntentVariable: String = "Countries" //This is an Intent variable (extra) from another activity
var DataToBeFetched : List<String>? = null
if (IntentVariable == "Countries")
{
  DataToBeFetched = ProjectDataLists.Countries
}
else if (IntentVariable == "Cars")
{
  DataToBeFetched = ProjectDataLists.Cars
}

我希望 Activity class 的最后一部分在没有 if/else

的情况下完成

你可以使用反射:

import kotlin.reflect.full.companionObject
import kotlin.reflect.full.memberProperties

class ProjectDataLists {
  companion object {
    var Countries: List<String> = listOf("USA", "Canada", "Australia", "UK")
    var Cars: List<String> = listOf("Toyota", "Suzuki", "Honda", "Ford")
  }
}

var intentVariable = "Countries"

val dataToBeFetched = (ProjectDataLists::class
  .companionObject!!
  .memberProperties
  .first { it.name == intentVariable }   // Will crash with NoSuchElementException if intentVariable is not existing
  .call(ProjectDataLists) as List<*>)
  .filterIsInstance<String>()

println(dataToBeFetched)   // Output: [USA, Canada, Australia, UK]

但是如果你的伴随对象中只有几个列表,我建议不要使用反射。请注意,您可以使用 when:

来简化 if 语句
val dataToBeFetched = when (intentVariable) {
  "Countries" -> ProjectDataLists.Countries
  "Cars"      -> ProjectDataLists.Cars
  // and more here ...
}

这是非常可读的,与反射相比非常明确和安全。