2012-05-13 1 views
7

Ich arbeite an der Programmierung eines grundlegenden Media Players, und ich habe einige Probleme beim Schreiben von polymorphem Code, was ich studiert habe, aber noch nie zuvor implementiert habe.Polymorphie: Ableiten von einem geschützten Member in einer Basisklasse?

Es gibt vier relevante Klassen: MediaInfo, MovieInfo, Media und Movie.

MediaInfo ist eine abstrakte Basisklasse, die Informationen enthält, die für alle Mediendateien relevant sind. MovieInfo erbt von MediaInfo und fügt einige Informationen hinzu, die für Videodateien spezifisch sind.

Media ist eine abstrakte Basisklasse, die alle Mediendateien darstellt. Film erbt von Media.

Nun Medien enthält die folgende Codezeile:

protected MediaInfo info; 

Innen Medien, ich habe Accessoren, die Informationen von Mediainfo extrahieren. Innerhalb von Movie möchte ich jedoch über Zugriffsmethoden verfügen, die auch Informationen aus MovieInfo extrahieren.

Also, was ich in Film tat, war:

protected MovieInfo info; 

Und innerhalb des Konstruktors:

this.info = new MovieInfo(path); 

Aber jetzt habe ich eine Accessor:

/// <summary> 
/// Gets the frame height of the movie file. 
/// </summary> 
public string FrameHeight 
{ 
    get 
    { 
     return this.info.FrameHeight; 
    } 
} 

Das Problem ist, FrameHeight ist ein Accessor, der nur in MovieInfo verfügbar ist. this.info wird als MediaInfo behandelt, obwohl ich es als MovieInfo deklariert habe und der Code daher einen Fehler generiert.

So, um mein Problem in einer allgemeineren Frage zusammenzufassen: Wie leite ich in einer abgeleiteten Klasse von einer geschützten Basisvariablen in der Basisklasse ab?

Tut mir leid, wenn das ein wenig verwirrend war, würde ich gerne alle unklaren Details klären.

Antwort

6

Sie könnten die Basisklasse generic in der Art der MediaInfo machen es enthält:

public abstract class Media<T> where T : MediaInfo 
{ 
    protected T info; 
} 

Dann können Sie festlegen, dass MovieMovieInfo Arten behandelt:

public class Movie : Media<MovieInfo> 
{ 
    public string FrameHeight 
    { 
     get { return this.info.FrameHeight; } 
    } 
} 
+1

@Daniel - Ich denke Generika sind die einzige (typsichere) Lösung für die Struktur, die Sie gegeben haben. Sie könnten es auf nicht-generische Weise tun, wenn Sie das 'info'-Feld aus der' MovieInfo'-Klasse in seine Unterklassen verschieben könnten. – Lee

1

Hier ist eine nicht-generische Alternative:

protected MovieInfo info { get { return (MovieInfo)base.info; } } 

Abhängig In der Situation kann dies besser sein als Lee's Lösung. Ich persönlich mag seine bessere, denke nur allgemein.