Неоднозначная перегруженная ссылка на метод при использовании Any - PullRequest
2 голосов
/ 27 февраля 2020

У меня проблема с тем, что я хочу использовать обобщенный тип c, и этот тип перегружен методами с Collection и varargs. Когда я использую Любой в качестве параметра типа, я не могу передать список в качестве аргумента.

    val productType = ComboBox<Any>("Product type")
//    public void setItems(Collection<T> items) {
//    public void setItems(T... items) {
    productType.setItems(listOf("1","2")) // Not possible

Есть ли лучшее решение, кроме преобразования списка в массив с помощью: productType.setItems(*listOf("1","2").toTypedArray())

Редактировать: Рабочий пример, чтобы попробовать:

   class Foo<T>() {
        fun setItems(items: Collection<T>) {}
        fun setItems(vararg items: T) {}
    }
        val f = Foo<Any>()
        f.setItems(listOf("1", "2"))

Ответы [ 3 ]

1 голос
/ 27 февраля 2020

Вы можете добавить метод расширения, вызывающий нужную перегрузку без двусмысленности:

fun <T> ComboBox<T>.setCollection(items: Collection<T>) { this.setItems(items) }

, а затем

productType.setCollection(listOf("1","2"))
0 голосов
/ 28 февраля 2020

Следующее должно работать

fun <T>setProductTypeItems(productTypes: List<T>) {
    (productType as ComboBox<T>).setItems(productTypes)
}
0 голосов
/ 27 февраля 2020

Если вам действительно нужно вызвать перегрузку, которая принимает Collection<T> (например, у него есть некоторые побочные эффекты, которых нет у другого), то есть решение, которое говорит компилятору сделать это.

Это похоже на: Как справиться с неоднозначностью разрешения перегрузки функций с обобщениями?

В принципе, вы можете сделать непроверенное приведение , которое будет ограничивать аргумент типа ComboBox, чтобы List<String> больше не совпадал с подписью с vararg типа аргумента, и есть только подпись, принимающая Collection, который соответствует.

Для этого вам нужно чтобы выбрать аргумент нового типа, скажем R, который удовлетворяет обоим условиям:

  • List<R> не является подтипом R
  • List<R> все еще является подтипом Collection<R>

Можно отметить, что тип, который мы можем использовать как R, равен String, давая это:

@Suppress("UNCHECKED_CAST")
(productType as ComboBox<String>).setItems(listOf("1","2"))

Однако, если поведение две перегрузки идентичны, проще передать массив в вару перегрузка rg с использованием *list.toTypedArray(), как вы и сказали.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...