2017-03-23 9 views
-2

KlassenForce-Liste <Base> = Liste <Derived> & Act Wie Liste <Derived>

public class Building 
{ 
    public string Name = "Not To Be Seen"; 
    ... 
} 

public class School: Building 
{ 
    public int NoOfRooms = 200; 
    public string Address = "123 Main St."; 
    ... 
} 

Tor (n einige andere Klasse/Use Case)

// This is a simple example, in reality this code is far more complex 
// the class "School" is private from the program 
List<Building> city = new List<School>(); 
// city will only have properties of the class School (or at least those are the only properties seen) 

Console.WriteLine(city[0].NoOfRooms.ToString()) // Outputs 200 
Console.WriteLine(city[0].Name) // Should not output anything 

Dies scheint, wie sollte es durchaus möglich sein, je nach richtig die Listen konvertieren. Aber ich kann mir nicht vorstellen, wie ich das zur Arbeit bringen soll. Es scheint, dass es Kovarianz beinhaltet, aber ich möchte nicht wollen eine unveränderliche Liste oder einen Typ. Bietet C# diese Art der Konvertierung nicht leicht an (d. H. Die Basisklasse kann eine abgeleitete Klasse vollständig nachahmen)?

Dank

+0

Ihr Beispiel ist falsch, 'List Jill' hat keine Eigenschaften' ClassRoom' Es ist eine Liste ... –

+0

Wie erwarten Sie, dass ein 'public' Feld für eine abgeleitete Klasse nicht sichtbar ist? –

+0

Und nein, man kann sich nicht wie ein Lehrer benehmen, der Zugriff auf Eigenschaften, die nur einem Lehrer auf einer Person gehören, wird niemals funktionieren ..... Ich würde wahrscheinlich dein Erbe hier überdenken ... und ich bin der Meinung, dass du es bist Verwenden Sie keine Vererbung –

Antwort

0

aktualisiert - Da Sie völlig Ihr Beispiel geändert, ich werde meine Antwort aktualisieren, um das neue Beispiel zu reflektieren. Ich mache das nur einmal; Wenn meine Antwort mit der Frage nicht übereinstimmt, liegt es daran, dass OP während der Bearbeitung unnötige Änderungen vornimmt.


Es gibt ein paar Probleme hier. Es ist nicht möglich, dass eine List<Base> Variable auf eine List<Derived> Instanz verweist. Dies liegt zum Beispiel daran, dass List<Base> Operationen zum Hinzufügen einer Base-Instanz zu List implementieren muss, und eine List<Derived> kann einen solchen Vorgang nicht unterstützen.

Allgemeiner definiert der Referenztyp (Typ, für den die Variable deklariert ist) die Schnittstelle, über die der aufrufende Code den Wert verwenden kann. Wenn Sie also in Ihrem Beispiel city[0].NoOfRooms sagen können, muss city als List<School> deklariert werden. Eine School könnte immer noch in einer List<Building> gespeichert werden, aber wenn Sie einen Artikel aus einer solchen Liste erhalten, müssen Sie versuchen, zu School zu werfen, bevor Sie die NoOfRooms Eigenschaft verwenden. (Und es sollte angemerkt werden, dass wenn Sie sich dabei befinden, schlägt es einen Designfehler vor.)

Der andere Teil Ihrer Frage hat mit dem Verbergen der Name Eigenschaft zu tun.

In einigen Sprachen können Sie einen solchen Effekt durch "private Vererbung" erhalten - aber das ist in C# keine Sache. Das nächste, was Sie tun könnten, ist nicht von Building abgeleitet, aber möglicherweise ein (privates) Building-Typ Feld oder Eigenschaft enthalten. Dann wäre es natürlich nicht möglich, eine School in einer List<Building> überhaupt zu speichern. Der andere Ansatz wäre School überschreiben die Name Eigenschaft mit einem Getter, der nichts zurückgibt, was eigentlich näher an dem ist, was Ihre Code-Kommentare vorschlagen.

0

sich nach den Anmerkungen zu Ihrer Frage, ein Objekt in Ihrem List<Building> nicht willkürlich in eine School gegossen werden kann, wenn sie ursprünglich als School Objekt (oder einer Klasse abgeleitet von School) errichtet wurde. Überlegen Sie, was passieren würde, wenn Sie eine andere Klasse mit dem Namen Hospital hätten, die von Building abgeleitet ist und deren eigene Eigenschaft say NumberOfPatients hatte und dies eines der Objekte in dieser Liste war.Sie können einfach keine Hospital Instanz in eine School umwandeln und die Eigenschaften aufrufen, die nur auf School verfügbar sind - es würde einfach keinen Sinn machen, dies zu tun.

Das heißt du noch ein List<Building> speichern jede Art von Building Objekte, einschließlich der abgeleiteten diejenigen haben können (so dass Sie eine gemischte Liste haben enthält Building, School und Hospital Objekte). Dann könnten Sie eine Auflistung von Objekten eines bestimmten abgeleiteten Typs über Linq OfType (fügen Sie an den Anfang Ihrer Datei using System.Linq;). So etwas wie buildingList.OfType<School>() würde Ihnen eine Aufzählung von nur School Objekte, die Sie jetzt durchlaufen können und rufen Sie Methoden/Eigenschaften nur unter School.

Verwandte Themen