C # "Umbenennen" -Eigenschaft in abgeleiteter Klasse

8

Wenn Sie das lesen, werden Sie sehr versucht sein, Ratschläge zu geben wie "das ist eine schlechte Idee aus folgendem Grund ..."

Bear mit mir. Ich weiß, dass es andere Wege gibt, dies zu erreichen. Diese Frage sollte als Kleinigkeit betrachtet werden.

Nehmen wir an, Sie haben eine Klasse "Transaktion" mit Eigenschaften, die für alle Transaktionen wie Rechnung, Bestellung und Lieferschein gelten.

Nehmen wir das einfache Beispiel der Transaktion "Amount", das der wichtigste Geldbetrag für eine bestimmte Transaktion ist.

%Vor%

Dieser Betrag kann einen spezifischeren Namen in einem abgeleiteten Typ haben ... zumindest in der realen Welt. Zum Beispiel sind die folgenden Werte eigentlich alle gleich:

  • Transaktion - Betrag
  • Rechnung - Zwischensumme
  • PurchaseOrder - Gesamt
  • Verkaufsbeleg - Betrag

Nun möchte ich eine abgeleitete Klasse "Rechnung", die eine Zwischensumme anstelle der generisch benannten Betrag hat. Im Idealfall wären beide der folgenden Aussagen zutreffend:

  1. In einer Instanz von Transaction wäre die Amount-Eigenschaft sichtbar.
  2. In einer Instanz von Invoice wäre die Amount-Eigenschaft ausgeblendet, aber die Subtotal-Eigenschaft würde intern darauf verweisen.

Die Rechnung sieht so aus:

%Vor%

Aber natürlich ist Transaction.Amount immer noch in jeder Invoice-Instanz sichtbar.

Vielen Dank für einen Blick!

    
Eric Burcham 07.09.2012, 21:28
quelle

5 Antworten

5

Danke für die Hilfe.

OK, natürlich können Sie öffentliche Eigenschaften für die Basisklasse nicht ausblenden, wenn die abgeleitete Klasse eine Basisinstanz ist. Irgendwo tief in meinem Gehirn wusste ich das schon. Doh!

Ich habe den syntaktischen Zucker dazu gebracht, sich so zu verhalten, wie ich es für den Verbraucher wollte, indem ich eine dritte Klasse namens TransactionBase verwende. Diese Klasse ist abstrakt und enthält das geteilte, nicht mit Alias ​​versehene Zeug, das für alle Transaktionen wie Währung, Wechselkurs, Datum und Uhrzeit der Erstellung / Änderung, Transaktionsdatum usw. zusätzlich zu Alias-Dingen wie Betrag existiert.

Hier zeige ich nur die Eigenschaft Betrag in Frage:

%Vor%

Dann sieht die Transaktion so aus:

%Vor%

und Rechnung:

%Vor%

Und der Zugriff funktioniert so, wie ich es wollte:

%Vor%

Die Antwort auf meine ursprüngliche Frage lautete also: "Nein", Sie können öffentlich geerbte Mitglieder nicht verbergen. Die obige Lösung täuscht es vor, direkt auf das geschützte Element in den abgeleiteten Typen zuzugreifen, aber es ist immer noch irgendwie nervtötend. Zu viel tippen.

Natürlich, jetzt, wo ich mit all dem herumgespielt und gepiddelt habe, sehe ich, dass eine bessere Lösung die geschützten Mitglieder komplett auswirft und mir ein wenig Tipparbeit erspart. Übrigens, es ist mir peinlich, dass ich nicht gleich zu dieser Lösung gesprungen bin.

BEARBEITEN: Eigentlich könnte das erste Appraoch in meiner Antwort besser sein. Mit dem zweiten würde ich "Betrag" oder "Zwischensumme" verlieren, wenn ich von einer Transaktion auf eine Rechnung umwandele.

%Vor%     
Eric Burcham 07.09.2012, 22:21
quelle
2

Kurz gesagt, Sie können das nicht tun.

Sie können dies durch Codieren an Schnittstellen nachahmen!

%Vor%     
Squirrelsama 07.09.2012 21:35
quelle
1

Ich würde empfehlen, in dieser Instanz Komposition über Vererbung zu verwenden. Der Hauptgrund ist, dass die Basisimplementierung von Transaction möglicherweise nie so verwendet wird, wie es durch Vererbung beabsichtigt ist. Sie können die Transaktion als geschütztes oder privates Mitglied der Rechnung ausblenden und mithilfe der öffentlichen Eigenschaften von Rechnung verfügbar machen / manipulieren.

Ein solches Beispiel könnte aussehen:

%Vor%     
Capps 07.09.2012 21:41
quelle
1

Das genaue Verhalten, nach dem Sie suchen, macht syntaktisch keinen Sinn. Wenn Rechnung Transaktion erbt, ist eine Art -Transaktion, und der Compiler benötigt diese, um alle seine Eigenschaften zu übernehmen.

Das allgemeine Verhalten, nach dem Sie suchen, ist, glaube ich, Verkapselung, die mit Schnittstellen erreicht werden kann.

%Vor%

Erfordern die Benutzer Ihres Codes, diese Schnittstellen zu verwenden, und dann sind die Implementierungsdetails für sie verborgen.

Nun können sich die Klassen so verhalten, wie Sie wollen. SubTotal ist weiterhin für die Klasse (Rechnung) sichtbar, wird jedoch für die Schnittstelle (IInvoice) ausgeblendet.

%Vor%     
McGarnagle 07.09.2012 21:39
quelle
0

Wie wäre es mit einem impliziten Konvertierungsoperator?

%Vor%     
Dennis 07.09.2012 22:10
quelle