Это был бы хороший кандидат для шаблона посетителей.
Давайте следующий базовый класс:
public abstract class Animal {
public abstract int Legs { get; }
public virtual void Speak() { Console.WriteLine("..."); }
public abstract void Accept(IAnimalVisitor visitor);
}
Обратите внимание на метод принимает. Здесь волшебство будет происходить с нашим объектом Visitor.
Мы реализуем их как наши производные животные, которые нам нужно обработать.
public class Cat : Animal {
public bool IsMewling { get; set; }
public override int Legs { get; } = 4;
public override void Accept(IAnimalVisitor visitor) { visitor.Visit(this); }
public override void Speak() { Console.WriteLine("Meow"); }
}
public class Dog : Animal {
public bool IsBarking { get; set; }
public override int Legs { get; } = 4;
public override void Accept(IAnimalVisitor visitor) { visitor.Visit(this); }
public override void Speak() { Console.WriteLine("Woof"); }
}
Хорошо, очень хорошо. Пара логических значений разных имен свойств, которые, возможно, потребуется проверить. Позволяет реализовать интерфейс IAnimalVisitor.
public interface IAnimalVisitor {
void Visit(Dog dog);
void Visit(Cat cat);
}
И, наконец, давайте создадим реализацию, которая видит, если животное говорит и действует по-разному в зависимости от состояния.
public class LetsHearWhatItHasToSay : IAnimalVisitor {
public void Visit(Dog dog) {
if (dog.IsBarking) dog.Speak();
else Console.WriteLine("Good boy!");
}
public void Visit(Cat cat) {
if (cat.IsMewling) cat.Speak();
else Console.WriteLine("Pretty kitty");
}
}
Хорошо, отлично. Позволяет связать все это вместе в небольшом образце.
void Main()
{
var animals = new List<Animal>
{
new Cat { IsMewling = true },
new Dog { IsBarking = false },
new Cat { IsMewling = false },
new Dog { IsBarking = true }
};
var visitor = new LetsHearWhatItHasToSay();
foreach (var animal in animals)
{
animal.Accept(visitor);
}
}
И мы получаем наши ожидаемые результаты
Meow
Good boy!
Pretty kitty
Woof
Преимущества использования посетителя в данном случае является то, что мы можем создать произвольное число герметизированных объектов, которые могут обрабатывать различные типы логических операций над классом иерархии безопасным типом без необходимости вносить изменения в эту иерархию классов. Недостаток заключается в том, что когда вы добавляете дополнительное Животное, которое хотите посетить, вам необходимо обновить каждого посетителя, который работает в иерархии.
Звучит как домашнее задание? – JonE
Конкретные вопросы о дизайне лучше подходят для http://programmers.stackexchange.com, хотя они могут видеть это как основанное на мнениях. –
@NexTerren при обращении к другим сайтам часто бывает полезно указать, что [перекрестная проводка нахмуривается] (http://meta.stackexchange.com/tags/cross-posting/info) – gnat