2017-02-16 18 views
0

Мне нужно подвергнуть объект одному из типов, которые имеют определенное свойство и метод. Во-первых, мне нужно проверить, является ли мой объект экземпляром одного из этих типов, а затем мне нужно передать его этому типу и выполнить некоторые действия.Как наложить объект на тип в C#

Как я могу это сделать без повторения кода?

var foo = GetAnimalById(animalId); // Animal type returned to foo 

var animal = new Animal(); // Animal class hasn't Age property and GiveVitamins method 
if (foo is Tiger) { 
    animal = foo as Tiger; 
    if (animal.Age >= 10) 
    { 
     animal.GiveVitamins(); 
    } 
} 
if (foo is Lion) { 
    animal = foo as Lion; 
    if (animal.Age >= 10) 
    { 
     animal.GiveVitamins(); 
    } 
} 
if (foo is Monkey) { 
    animal = foo as Monkey; 
    if (animal.Age >= 10) 
    { 
     animal.GiveVitamins(); 
    } 
} 
+3

Существует динамический пример отправки с помощью 'dynamic', но я оставлю это на данный момент. Похоже, что все животные могут делиться членами «Age» и «GiveVitamins», так почему бы не продвинуть их в базовый класс «Animal»? –

+0

Я думаю, что здесь что-то не так с дизайном. Почему в классе 'Animal' нет свойства' Age'? Можете ли вы назвать животное, которое не состарилось? – Sweeper

+0

Если вы не можете переместить 'Age' и' GiveVitamines' в 'Animal', подумайте о создании интерфейса, который содержит оба, пусть' Tiger', 'Lion' и' Monkey' реализуют этот интерфейс и проверяют эту реализацию. –

ответ

0

Я думаю, что с вашим дизайном что-то не так. Каждое животное должно иметь возраст, поэтому вместо того, чтобы иметь отдельный Age объект в Tiger, Lion и Monkey, переместите Age в категорию Animal.

Еще одна странная вещь в вашем дизайне заключается в том, что животные не дают витаминов. Они получают витамины. Я думаю, вы должны переименовать метод в ReceiveVitamins. Затем создать интерфейс вроде этого:

interface VitaminReceivable { 
    void ReceiveVitamins(); 
} 

Have Tiger, Lion и Monkey все реализуют этот интерфейс, то вы можете просто сделать:

var foo = GetAnimalById(animalId); // Animal type returned to foo 

var animal = new Animal(); // Animal class hasn't Age property and GiveVitamins method 
if (foo is VitaminReceivable) { 
    animal = foo; 
    if (animal.Age >= 10) 
    { 
     ((VitaminReceivable)animal).ReceiveVitamins(); 
    } 
} 

EDIT:

Теперь, когда я знаю, что вы не может быть Age в Animal, вы должны создать другой интерфейс:

interface Ageable { 
    int Age { get; } 
} 

Есть подклассы реализуют интерфейс, а затем вы можете написать это:

var foo = GetAnimalById(animalId); // Animal type returned to foo 

var animal = new Animal(); // Animal class hasn't Age property and GiveVitamins method 
if (foo is VitaminReceivable && foo is Ageable) { 
    animal = foo; 
    if (((Ageable)animal).Age >= 10) 
    { 
     ((VitaminReceivable)animal).ReceiveVitamins(); 
    } 
} 
+1

Ваше кастинг ужасно. Используйте «как» и будьте более могущественными. – eocron

+0

@eocron Какие еще решения существуют? Я не могу придумать ни одного. – Sweeper

+0

Животные дают витамины, когда их едят, предполагая, что животные. IsTasty установлен в true. – Zesty