【问题标题】:How to check if an object has a certain property如何检查对象是否具有特定属性
【发布时间】:2021-03-12 23:03:22
【问题描述】:

我有两个不同的类:

internal data class ClassB(
        @Json(name = "id") val id: String?,
        @Json(name = "name") val name: String?,
        @Json(name = "url") var contentUrl: String?,
        @Json(name = "mediaImageUri") val coverUrl: String?,
        @Json(name = "mediaVideoCoverImageUri") val videoCoverUrl: String?
        
)

internal data class ClassC(
        @Json(name = "tileId") val id: String?,
        @Json(name = "friendId") val friendId: String?,
        @Json(name = "profilePictureUri") var profilePicture: String?,
        @Json(name = "name") var name: String?
)

继承自同一个类:

internal open class ClassA(
        @Json(name ="type") var type: String?,
        @Json(name ="sponsor-offer") var offer: SponsorOffer?,
        @Json(name ="date") var date: Date?,
        @Json(name ="weight") var priorityWeight: Int?
)

我正在使用一个 API 调用,该调用返回一个 ClassA 列表并通过改造解析为一个列表,并且需要在将每个对象添加到本地 ArrayList<Any> 之前将其强制转换为其中一个子类。

我试图通过遍历返回的列表并检查 B 类和 C 类的专有属性来做到这一点。然后在将对象添加到本地数组之前将其转换为适当的对象。如何检查这些属性?有没有更好的方法来做我想做的事情?

classA.javaClass.kotlin.members.any 不工作

【问题讨论】:

    标签: android kotlin retrofit


    【解决方案1】:

    如果ClassBClassC 都扩展ClassA,那么你可以只使用is 关键字来检查类型然后强制转换它

    val thing: ClassA = getThing()
    if (thing is ClassB) {
        // thing should have been smart-cast to ClassB in here, or you can:
        val thingB = thing as ClassB
    }
    

    或者您可以使用when 块来检查可能的类型。

    或者您可以使用the safe-cast operator as?,如果您无法转换为该类型,则计算结果为 null:

    (thing as? ClassB)?.let { ... } ?: // it was null, so it's not ClassB, so...
    

    但是,如果您这样做是为了将它们放入 ArrayList<Any> 中,那么投射它们是没有意义的,该信息会丢失 - 它是 Anys 的列表!当您将它们取出时,您必须重新检查类型并投射每个项目。

    如果您想保存 ArrayList<ClassB>ArrayList<ClassC> 的单独列表,然后进行强制转换以便将它们放入正确的列表(仅接受该类型)是可以的 - 您将确切地知道您是什么摆脱那些

    【讨论】:

    • 感谢您的回复。我正在用 Retrofit 解析响应。如何让改造知道哪些项目要解析为 B 类,哪些项目要解析为 C 类?我假设您的第一个块不起作用,因为它仅将其识别为 A 类
    • 在您的代码中,ClassBClassA 之间没有关系,ClassC 也是如此。没有继承发生,它们都没有 ClassA 作为超类型 - 而且它们无论如何都不能!您不能在 Kotlin 中使用 open data class(无论如何目前都没有)。如果您在讨论 JSON 中的嵌套对象,请查看 stackoverflow.com/questions/32942661/…
    • 另一种方法(我不知道你到底在做什么,我几乎没有接触过改造)是创建一个sealed classClassBClassC 都派生自,并且在ClassA 中将其添加为(如果可选,则可以为空)参数 - 这样每个ClassA 都可以“包含”ClassBClassC,您可以轻松地将它们拉出。我不知道你如何解析这样的嵌套内容的细节,但它应该很常见吧!
    • 我最终为 A 类提供了 B 类和 C 类的所有属性。糟糕的解决方案,但我陷入了困境。谢谢你的时间,想!
    • 在那之后查看我的评论,这有点像,但看起来更像是应该如何组织,如果这是你的数据结构的话。希望成功!
    猜你喜欢
    • 2012-04-16
    • 2017-10-09
    • 2010-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多