@FlameArt

Почему C# не позволяет делать Downcast от родителя к потомку?

Интересно, почему C# принципиально не позволяет расширять базовый экземпляр, как в этом коде?

class People { public string name; }
class Person : People { public uint id; }

static void Main(string[] args)
{

        People jack = new People { name = "Jack" };
        Person jack_passport = (Person)jack; // InvalidCastException

}


Хочется понять на теоретическом уровне.

Задача простая: моя библиотека возвращает экземпляр, я хочу его дополнить и использовать в другом своём приложении. Звучит красиво и архитектурно логично, чтобы в приложении расширить этот экземпляр и добавить туда своих данных. Но почему этого нельзя?

Остаются только какие-то странные варианты, типа копировать все свойства вручную, или создавать переменную с ссылкой на родительский объект. Или что ещё страннее - инициализировать экземпляр известного типа сразу в библиотеке, делать Upcast в базовый класс, а потом в своей проге через Downcast приводить к своему, и такое приведение работает. Такого способа по идее не должно существовать в природе, потому что библиотека не должна знать ни о каких производных классах.

Интересно ещё, какие существуют правильные подходы или архитектуры к тому что я хочу.
  • Вопрос задан
  • 356 просмотров
Пригласить эксперта
Ответы на вопрос 5
freeExec
@freeExec
Участник OpenStreetMap
Интересно, почему C# принципиально не позволяет расширять базовый экземпляр, как в этом коде?

Потому, что объект создан и занимает в памяти 20 байт. И о не как не может кастнуться в объект который должен занимать 20 Мб.
Поэтому вам как не крути придётся создавать новый экземпляр.
Ответ написан
@tex0
Хочется понять на теоретическом уровне.

У вас есть два множества:
1) Person - большее множество, производное.
2) People - родитель, является подмножеством Person и входит него полностью.
Так вот - из большего(производного) множества вы можете выделить подмножество, т.к. это подмножество целиком и полностью входит в производное. А вот из меньшего(родительского) выделить большее(производное) никак нельзя. У вас тупо нет данных об остальных элементах производного множества.

А теперь на пальцах:
У вас есть листок бумаги. Он является составным объектом из всех потенциальных(!!!) произвольных его частей(вырезанных областей, оторванных кусков и т.п.). Получается что физически вы можете из этого листка бумаги выделить/оторвать/вырезать любой кусок, находящийся в его составе(приведение большего к меньшему), а вот из любого меньшего куска этого листка получить общий, производный, уже нет.
Именно по этому приведение базового к производному - некорректная операция с точки зрения логики и является, в вашем случае, ошибкой.
Ответ написан
Decadal
@Decadal
Почему для вас выглядит логичным каст экземпляра родителя в экземпляр потомка? А если потомок определяет особенные условия, которые нужны для его создания? А зависимости?
Ответ написан
yarosroman
@yarosroman Куратор тега C#
C# the best
Это не C# принципиально запрещает, а ООП.
Ответ написан
Alexeee
@Alexeee
Разработчик игр
Странно, что здесь не написали следующее:
class People { public string name; }
class Person : People { public uint id; }

static void Main(string[] args)
{

        People jack = new Person { name = "Jack" }; // Upcast
        Person jack_passport = (Person)jack;  // Downcast

}


Чтобы была возможность делать Downcast, нужно сначала сделать Upcast.
По идее, такой код должен работать, но я не уверен, что это нужно было автору.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы