Наследование дженериков c не может быть приведено - PullRequest
0 голосов
/ 15 января 2020

У меня проблема с наследованием пользовательского универсального кода c. Компилятор (Visual Studio для Ma c) жалуется на то, что наследующий generi c не может быть неявно преобразован в другой наследующий тип. Код моего кода выглядит следующим образом:

У меня есть интерфейс с именем IAnsededCommon и другой интерфейс, который унаследован от него, под названием IAnspted Android

public interface IAnsweredCommon

и

public interface IAnsweredAndroid : IAnsweredCommon

У меня есть два других класса, которые используют эти интерфейсы.

public abstract class ConstructorCommon<AnsweredType> where AnsweredType : IAnsweredCommon

и

public class ConstructorAndroid : ConstructorCommon<IAnsweredAndroid>

Это работает. Общий конструктор имеет переменную-член AnsptedType, позволяющую ему обрабатывать его как IAnsptedCommon и запускать код операционной системы c против него, в то же время позволяя конструктору Android обращаться к той же переменной-члену и обрабатывать его как IAnspted Android, что позволяет конструктор Android для запуска Android указанного кода c. Конструктор Android может обрабатывать вещи Android, специфицирующие c, передавая код агностии ОС c общему конструктору. Это работает и это то, что я хочу, так как позволяет мне расширить это до iOS. Теперь проблема в том, что у меня есть еще один слой поверх конструктора. Конструктор в основном реализует шаблон проектирования компоновщика, и поэтому у него есть много методов, которые нужно вызвать, чтобы создать объект с ответом. У меня есть классы директора, которые вызывают предопределенные методы конструктора для создания предопределенного объекта ответа.

public abstract class DirectorCommon<AnsweredConstructorType>
    where AnsweredConstructorType : ConstructorCommon<IAnsweredCommon>

и

  public class DirectorAndroid : DirectorCommon<ConstructorAndroid>

Компилятор жалуется на невозможность неявного преобразования Constructor Android в ConstructorCommon <\ IAnsweredCommon>. Я расширил конструктор Android для целей тестирования и временно изменил его на:

public class DirectorAndroid : DirectorCommon<ConstructorCommon<IAnsweredAndroid>>

Теперь, если я изменю интерфейс IAnspted Android на IAnsptedCommon, ошибка исчезнет ( как следует, так как это точно соответствует ограничению). Но если я изменю его на IAnspted Android, я получу ошибку. Я в замешательстве, так как IAnspted Android IS IAnsededCommon (наследование) и, следовательно, компилятор должен иметь возможность выгрузить IAnspted Android в IAnsptedCommon. В конце концов, это делается в классах конструктора. ПРИМЕЧАНИЕ. Я очистил код, чтобы его было легче читать (удаленные пространства имен, нерелевантный код и т. Д.), Поэтому код может быть «неработоспособным», но в любом случае, пожалуйста, укажите на любые ошибки, и я уверен, что это незначительная вещь, по которой я скучаю, и вы никогда не узнаете, произошла ли ошибка из-за очистки или это действительно ошибка.

1 Ответ

0 голосов
/ 15 января 2020

Это невозможно, class<A> нельзя присвоить class<B>, также если A происходит от B или наоборот.

Это будет работать, если ConstructorCommon будет интерфейсом, IConstructorCommon, и будет определен как:

interface IConstructorCommon<out AnsweredType> where AnsweredType : IAnsweredCommon

"out" делает его ковариантным.

Для замены может подойти абстрактный базовый тип с интерфейсом.

Ваша ошибка не имеет ничего общего с ограничением, то, как вы нашли совпадения, приводит к совпадению типов. Вы можете назначить ConstructorComman<Android> на ConstructorCommon<Android>, но не на ConstructorCommon<Answer>, независимо от того, есть ли ограничение или нет. Ограничения вам нужны, только если вы хотите вызывать специальные методы, которые есть только у вашего ограниченного типа.

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