Есть ли способ обойти это, используя интерфейсы или наследование?
Да.
Интерфейсы: создайте интерфейс IEat или IPet или любую другую концепцию, которую вы хотите представить.Сделайте так, чтобы в интерфейсе был метод Eat.Пусть Кошка и Собака реализуют этот интерфейс.Имейте свойство Pet этого типа.
Наследование: Создайте абстрактный базовый класс Animal или Pet или любую другую концепцию, которую вы хотите представить.Сделай абстрактный метод Eat на базовом классе.Пусть Кошка и Собака унаследуют от этого базового класса.Имейте свойство Pet такого типа.
В чем разница между этими двумя?
Используйте интерфейсы для моделирования идеи "X знает, как сделать Y".Например, IDisposable означает «Я знаю, как распорядиться важным ресурсом, который я держу».Это не факт о том, что объект является , это факт о том, что объект делает .
Использование наследования для моделирования идеи "X являетсявроде Y ".Собака - это разновидность животного.
Особенность интерфейсов в том, что вы можете иметь их столько, сколько захотите.Но вы можете наследовать только напрямую от одного базового класса, поэтому вы должны убедиться, что вы правильно поняли, если собираетесь использовать наследование.Проблема с наследованием заключается в том, что люди заканчивают тем, что создают базовые классы, такие как «Транспортное средство», а затем они говорят: «Военный автомобиль - это вид транспортного средства» и «Корабль - это вид транспортного средства», и теперь вы застряли: что является основойкласс Разрушителя?Это и корабль, и военный автомобиль, и не может быть одновременно . Очень тщательно выбирайте свою «опору наследования» .
Есть ли способ, которым я могу присвоить питомцу тип Object, но при этом получить доступ к свойствам того класса, который ему присвоен??
Да, в C # 4 есть, но не делают .Используйте интерфейсы или наследование.
В C # 4 вы можете использовать «динамический» для получения динамической отправки во время выполнения методу Eat для объекта, который находится в Pet.
Причина, по которой вы не хотите этого делать, заключается в том, что это может привести к краху и ужасной смерти, если кто-то поместит Фрукт или Ножовку в свойство питомца , а затем попытается заставить его съесть.Целью проверок во время компиляции является уменьшение хрупкости программ.Если у вас есть способ сделать больше проверок во время компиляции, используйте его.