Angenommen, ich habe eine Sammlung von Objekten, die alle von einer Basisklasse erben. So etwas wie ...Wie ändere ich diesen Entwurf, um einen Downcast zu vermeiden?
abstract public class Animal
{
}
public class Dog :Animal
{
}
class Monkey : Animal
{
}
Nun müssen wir diese Tiere füttern, aber sie sind nicht zu wissen erlaubt, wie sie sich zu ernähren. Wenn sie könnten, wäre die Antwort einfach sein:
foreach(Animal a in myAnimals)
{
a.feed();
}
Allerdings können sie nicht wissen, wie sich selbst zu ernähren, so wollen wir so etwas wie dies tun:
class Program
{
static void Main(string[] args)
{
List<Animal> myAnimals = new List<Animal>();
myAnimals.Add(new Monkey());
myAnimals.Add(new Dog());
foreach (Animal a in myAnimals)
{
Program.FeedAnimal(a);
}
}
void FeedAnimal(Monkey m) {
Console.WriteLine("Fed a monkey.");
}
void FeedAnimal(Dog d)
{
Console.WriteLine("Fed a dog.");
}
}
Natürlich, das gewonnen nicht kompilieren, da es einen Downcast erzwingen würde.
Es fühlt sich an, als ob es ein Designmuster oder eine andere Lösung mit Generika gibt, die mir aus diesem Problem helfen, aber ich habe noch nicht meine Finger darauf gelegt.
Vorschläge?
(seit Anforderung) Die 'OfType' ist in Ordnung, aber Sie müssten so viele' OfType's wie Sie Rassen haben - so wird Visitation schließlich. Die Wörterbuch/Delegierten-basierte Besucher-Implementierung, die hier diskutiert wird, ist einer von vielen gültigen Ansätzen, müsste aber ein wenig über die Vererbung nachdenken ... –
... d. Wenn ich eine Aktion für "Hund" registriert habe, aber eine "Collie" -Instanz hinzufüge, würde sie brechen. Auch die Lambdas lassen sich (glaube ich) zu AddFeeder (GiveBananasTo) vereinfachen; AddFeeder (ThrowBiscuitsAt). Aber eine vernünftige Diskussion; - = p –
Der OfType, den ich wirklich erwähnt habe, um zu zeigen, wie ein Downcast in Ordnung ist, solange Sie es einkapseln, um es sicher zu machen, als ein Intro für den Rest der Antwort. –