如何指定"accepts generic sub-type of a generic type"?

How to specify "accepts generic sub-type of a generic type"?

我正在尝试实现接受通用参数的函数定义,只要它扩展了另一个特定的通用类型。简而言之;参数 A 必须扩展参数 B,其中 A 和 B 都是通用的。

下面是我的示例

abstract class Endpoint<T>(
) {

    private val myList: MutableMap<Class<T>, MutableList<((T) -> Unit)>> = mutableMapOf()

    fun addToList(
        index: Class<E>, <-- E extends T
        value: (E) -> Unit
    ) {
        myList[index] = (myList[index] ?: mutableListOf()).apply { add(value) }
    }

}

用法示例为

部分封印class

sealed class MainSealedClass {
    data class ChildClass(val someParam: Int): MainSealedClass()
}

以及函数调用

anEndpointInstance.addToList(MainSealedClass.ChildClass::class.java, "some value")

我希望不必在抽象 class 声明中定义 E,因为 T 已经在那里定义了。

我也尝试过以下操作:

将 myList 定义为接受扩展 T 的键

val myList: MutableMap<Class<in T>, MutableList<String>>

将 E 定义为 T 类型(找不到如何在函数中指定它扩展 T

    fun <E:T> addToList(
        index: Class<E>,
        value: (E) -> Unit
    ) {
        myList[index] = (myList[index] ?: mutableListOf()).apply { add(value) }
    }
    fun addToList(
        index: Class<in T>,
        value: (E) -> Unit
    ) {
        myList[index] = (myList[index] ?: mutableListOf()).apply { add(value) }
    }
    fun <E> addToList(
        index: Class<E>,
        value: (E) -> Unit
    ) where E : T {
        myList[index] = (myList[index] ?: mutableListOf()).apply { add(value) }
    }

但它永远行不通。有没有办法做到这一点?我无法在 Whosebug 中找到任何有关此场景的答案。

你的方差倒转了。如果你想让你的地图接受 类 的 T 子类型,那么它需要是 <out T>。如果您不检查密钥,您可能只输入 Class<*>.

您声明函数的第一种方式是正确的。

abstract class Endpoint<T>(
) {

    private val myList: MutableMap<Class<out T>, MutableList<String>> = mutableMapOf()

    fun <E : T> addToList(
        index: Class<E>,
        value: String
    ) {
        myList.getOrPut(index, ::mutableListOf).add(value)
    }

}