Теперь я представляю ваш код так, что у вас есть абстрактный базовый класс, содержащий метод (GetFruit
), который возвращает интерфейс, который я назову IFruit
. В производном классе вы хотите иметь возможность возвращать (из этого самого метода GetFruit
) объект Apple
, который реализует интерфейс IFruit
.
Однако, как бы это ни было удобно, Спецификация общего языка (CLS) не позволяет совместимым языкам поддерживать ковариацию возвращаемого типа . Это включает в себя все языки .NET, такие как VB.NET и C #. Существует много дезинформации о том, почему именно возникает это ограничение и что именно отвечает за это ограничение, но простой ответ заключается в том, что вы не можете сузить тип возвращаемого значения для метода в производном классе до более конкретного деривации.
Это означает, что, хотя Apple
реализует IFruit
, вы не можете набрать метод в производном классе, чтобы вернуть Apple
. Переопределенные методы должны иметь такую же сигнатуру возвращаемого значения, как и у их базы. Таким образом, вместо этого каждый метод должен возвращать объект того же типа (IFruit
) для всех классов, производных от вашего базового класса. Просто изменив возвращаемое значение метода в Ваш производный класс того же типа, что и метод в базовом классе, решит вашу проблему.
Вы упомянули возможность сделать базовый класс универсальным, и, хотя это, вероятно, сработало бы, оно, похоже, создает ненужную сложность. Используя мой надуманный пример выше, поскольку Apple
полностью реализует интерфейс IFruit
, вы должны получить все преимущества проверки типов и даже Intellisense, просто возвращая IFruit
из ваших производных классов.
РЕДАКТИРОВАТЬ: Если вы открыты для чего-то немного хакерского, вы всегда можете повторно объявить метод в вашем производном классе (пометив его как new
или Shadows
) , Это позволит вам вернуть любой тип объекта, который вы хотите, независимо от сигнатуры метода в базовом классе. Однако помните, что нет способа повторно объявить и переопределить метод одновременно, так что вы на самом деле не полиморфны.