5 Stimmen

Casting und Schnittstellenvererbung

Jedes Element hat eine Schnittstelle, IItem . Darüber hinaus gibt es eine Schnittstelle, die als IDrawableItem die von Item erbt.

Der folgende Code versucht, ein zeichenbares Element zu zeichnen, kann dies aber nicht, da die Sammlung, die diese Klasse speichert, nur IItem . Sie können alles hinzufügen, was von IItem zu dieser Klasse, aber die Verwendung anderer Methoden kann nur durch Casting erreicht werden.

foreach (var item in Items) {
    item.Draw();               // The casting would go here.
}

Ich weiß, wie man wirft, as usw. ... aber ist das akzeptabel? Ist es eine bewährte Praxis?

Ich frage mich nur, ob es andere Möglichkeiten gibt, mit solchen Szenarien umzugehen.

0 Stimmen

Der folgende Code versucht, ein zeichenbares Element zu zeichnen, kann dies aber nicht, da die Sammlung dieser Klasse nur IItem akzeptiert. - WARUM? Erzählen Sie uns ein wenig über das Design. Können Sie es ändern?

0 Stimmen

Jasons Code wird Sie aus Ihrem Dilemma befreien. Die Frage ist, ob dies das richtige Design für Ihre Objekte ist, und das ist wirklich schwer zu sagen, von 2 Zeilen der Beschreibung.

0 Stimmen

Vielleicht verwenden Sie eine Sammlung, die IDrawbleItem s stattdessen speichert?

11voto

jason Punkte 227577

Utilice Enumerable.OfType um nur die Elemente von Items die umsetzen IDrawableItem :

foreach(var item in Items.OfType<IDrawableItem>()) {
    item.Draw();
}

Um die Frage zu beantworten, die Nanook in den Kommentaren gestellt hat, wird der obige Code wahrscheinlich in einen Code übersetzt, der dem folgenden entspricht:

foreach(var item in Items) {
     if(item is IDrawableItem) {
        ((IDrawable)item).Draw();
     }
}

In Wirklichkeit gibt es natürlich einen Iterator hinter den Kulissen, der etwa so aussieht:

public static IEnumerable<T> OfType<T>(this IEnumerable<TSource> source) {
    if(source == null) {
        throw new ArgumentNullException("source");
    }
    foreach(TSource item in source) {
        if(item is T) {
            yield return (T)item;
        }
    }
}

Dies zeigt also, dass wir wahrscheinlich nur durch Items einmal. Natürlich ist es nicht erforderlich, dass OfType wird wie oben beschrieben implementiert, aber das ist das Sinnvollste, was man tun kann.

1voto

Rafał Dowgird Punkte 40450

Zwei alternative Lösungen:

  • Bewahren Sie die Auslosungen in einer separaten Sammlung auf.
  • hinzufügen DrawIfPossible() Methode zu IItem . IDrawableItem sollte sie überschreiben, um Draw() Sonstiges IItem() Implementierer sollten eine leere Implementierung haben.

Eine explizite Typabfrage wird als Zeichen dafür angesehen, dass mit dem Entwurf etwas nicht in Ordnung ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X