Предположим, у меня есть несколько общих типов
Травоядных, каждый из которых связан с определенным типом
Овощей, который он знает для потребления. Далее предположим, что я хочу иметь возможность сбрасывать любой общий овощ на любое травоядное животное и позволить последнему съесть его, если это возможно (в противном случае либо вызвать исключение, либо ничего не делать).
Самый простой способ сделать это, вероятно, вообще отказаться от непатентованных продуктов, что-то вроде
Код: Выделить всё
abstract class Herbivore {
public abstract void Eat(Vegetable v);
}
class Bunny : Herbivore {
public override void Eat(Vegetable v) {
if (v is Carrot c)
// Do carrot-specific stuff here
{}
}
}
Достаточно функционально, но необходимость добавлять первую строку приведения и/или проверки типов в каждый метод каждого производного класса кажется ненужной. Поэтому я подумал сделать что-то вроде этого:
Код: Выделить всё
abstract class Herbivore {
public abstract void Eat(Vegetable v);
}
abstract class Herbivore : Herbivore where T : Vegetable {
public override void Eat(Vegetable v) {
if (v is T t)
Eat(t);
}
protected abstract void Eat(T t);
}
class Bunny : Herbivore {
protected override void Eat(Carrot c) {
// Do carrot-specific stuff here
}
}
Думаю, это немного чище, поскольку все приведение происходит в Herbivore, а не в каждом производном классе, но (1) это по-прежнему кажется немного неэлегантным и (2) это действительно работает только для одного уровня наследования: если бы я хотел получить подкласс LopEaredBunny, который сохраняет большую часть функциональности Bunny, но также имеет поведение, специфичное для подкласса Carrot Parsnip, я бы, вероятно, просто сделал это с помощью приведение аргумента Carrot в телах методов LopEaredBunny.
Не упускаю ли я более чистый и универсальный способ выполнения подобных задач?
Подробнее здесь:
https://stackoverflow.com/questions/798 ... -with-gene