& ldquo; класс A < T extends SomeClass < T > & rtquo; работает не так, как класс B < T extends SomeInterface < T > > ? (Да)

В специальном случае есть невероятно простое и короткое решение.

Сегодня я столкнулся с аналогичной проблемой, с внешним XML-файлом, который содержит значения TRUE / FALSE, которые должны иметь логическое значение значение.

Если для приложения не обязательно, чтобы десериализованный документ содержал собственный bool, но он просто требует десериализации его для чего-то, что ограничено любыми двумя альтернативными значениями, тогда можно просто использовать перечисление (здесь для атрибута в качестве примера):

public enum BOOL {FALSE, TRUE};

public MyClass
{
    [XmlAttribute]
    public BOOL MyStrangeBooleanAttribute {get; set;}
}

Это будет просто десериализовать без каких-либо проблем из элемента вроде этого

<MyClass MyStrangeBooleanAttribute = "TRUE" />

Конечно, это невозможно использовать свойство в коде для прямых логических операций, например

if (MyStrangeBooleanAttribute) // ... doesn't work

Я думаю, что, возможно, с этим можно было бы справиться, указав неявное преобразование, но я его не тестировал, потому что я не это нужно.

2
задан RFS 24 February 2019 в 11:07
поделиться

2 ответа

Если у класса Box нет конструктора с T, то вы можете создать класс, расширяющий Box. Например:

class NewBox extends Box<NewBox> {
    ...
}

Затем вы можете создать экземпляр G, например:

G<NewBox> g = new G<>(new NewBox());

Но в вашем случае Box имеет конструктор Box(T val){...}, тогда NewBox требуется соответствие конструктора super ] вроде:

class NewBox extends Box<NewBox> {
    NewBox(NewBox val) {
        super(val);
    }
}

Чтобы создать его, вы должны получить нулевое значение, иначе это приведет к бесконечному вложению:

G<NewBox> g = new G<>(new NewBox(new NewBox(new NewBox(null))));

Обновление: , чтобы ответить Исходный вопрос: G <T extends Box<T>> означает, что T должен быть типом Box или любым потомком Box. Как вы правильно заметили, это приведет к бесконечной вложенности. Но вы все еще можете создать этот экземпляр без создания дополнительного класса (как указано выше с NewBox), используя Wildcard и null в качестве параметра для конструктора класса G, например: 1125]

G<?> tg = new G<>(null);
0
ответ дан Ruslan 24 February 2019 в 11:07
поделиться

Если вас беспокоит ограничение типа T extends Box<T>, это означает, что только типы, которые могут быть указаны в качестве параметра типа, должны расширяться Box.

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

Позвольте привести пример. Скажем, у нас есть следующие операции

interface Op1<T>{
    void doOp1(t: T): T
}

interface Op2<T> {
   void doOp2(t: T): T
}

class MyClass implements Op1<MyClass>, Op2<MyClass>{
    //By implementing Op1 and Op2 you
    //specify that operations doOp1 and doOp2
    // can be applied to variable of typr MyClass
}

И теперь вы хотите реализовать свой универсальный контейнер, который принимает элементы типов Op1 и Op2, которые могут быть применены к

class MyContainer<T extends Op1<T> & Op2<T>>{
   //you can apply doOp1 and doOp2 to any variable of the type T
}

MyContainer<MyClass> t = //... Ok
MyContainer<Integer> t = //... Not ok
[1111 ] В функциональном программировании подобное (но не совсем то же самое) называется классом типов

0
ответ дан Some Name 24 February 2019 в 11:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: