Vererbung und gemeinsame statische Felder

8

Angenommen, ich habe eine generische abstrakte Klasse, die einige Standardfunktionen für Konstruktoren bietet, sodass Sie den Code in Ihren geerbten Klassen nicht wiederholen müssen:

%Vor%

Nun ist das Problem, wenn ich zwei vererbte Klassen schreibe:

%Vor%

Wie Sie sehen können, sind diese beiden Arten wirklich typsichere Aufzählungen. Sie bieten nur vordefinierte Werte und können nicht für andere Zwecke instanziiert werden.

Frage

Das Problem liegt daran, dass beide geerbten Klassen die gleichen generischen Typen mit der Basisklasse Base<string, string> verwenden. Und die Art und Weise, wie generische Klassen und statische Felder funktionieren, ist die, dass für jeden generischen Typ (oder eine Kombination aus mehreren) ein neues statisches Feld erstellt wird.

In meinem Fall ist die Kombination string, string , deshalb gibt es nur ein statisches Basisklassenfeld und es enthält 4 Werte, anstatt zwei statische Felder mit jeweils zwei Werten .

Wie kann ich dieses Problem lösen und diese trennen, während diese Funktionalität weiterhin in der Basisklasse hält , damit ich meinen Code nicht wiederhole?

Das Ändern des Felds von "static" in "instance" funktioniert nicht, weil sie 4 Instanzen mit jeweils nur einem Wert ergeben ...

    
Robert Koritnik 19.06.2012, 15:21
quelle

5 Antworten

9

Das wird funktionieren. Ich glaube, es ist bekannt als das seltsam wiederkehrende Vorlagenmuster, aber zitiere mich nicht dazu

%Vor%

Der 'kuriose' Teil ist, dass die Definitionen von One und Two sich selbst als Typparameter benutzen dürfen!

    
AakashM 19.06.2012, 15:30
quelle
6

Das Problem tritt natürlich auf, weil Ihre zwei Klassen dieselbe Basisklasse mit den gleichen generischen Typargumenten verwenden. Dies bedeutet, dass sie die gleichen statischen Mitglieder teilen.

  

Wie überwinde ich dieses Problem und trenne es unter Beibehaltung dieser Funktionalität in der Basisklasse, damit ich meinen Code nicht wiederhole?

Ein Ansatz wäre, Ihr Dictionary in einem Wörterbuch zu erstellen, das auf dem aktuellen Laufzeittyp basiert:

%Vor%

Dies führt dazu, dass alle Nachschlagevorgänge zwei Phasen haben, da Sie den aktuellen Typ suchen müssen dann den Wert in diesem Wörterbuch nachschlagen, aber er ist nicht darauf angewiesen, Ihre Unterklassen-API überhaupt zu ändern.

    
Reed Copsey 19.06.2012 15:33
quelle
2

Dies beantwortet die Frage nicht direkt, sondern bietet stattdessen ein alternatives Design, um hoffentlich das gleiche Ziel zu erreichen.

Es scheint mir, als ob Sie versuchen, eine Basisklasse für etwas zu verwenden, das kein Basisverhalten oder zumindest kein statisches Verhalten ist.

Trennen Sie die Bedenken, eine Nachschlageliste item zu sein, und geben Sie die Nachschlagelistenreferenz an.

Wenn Sie versuchen, bekannte Lookups bereitzustellen, würde ich den Lookup-Listenreferenz getrennt von den Lookup-Elementen (wie in, nicht ein statisches Mitglied):

%Vor%

Dann kann jeder Typ einfach auf das entsprechende Wörterbuch zeigen, oder es benennen und durch Reflexion darauf zugreifen oder einen Func bereitstellen:

%Vor%

Damit können Sie auch die Liste selbst von den Elementen in der Liste trennen (vielleicht durch Injektion).

Beachten Sie auch, dass, wenn die Basisklasseninstanzen einen Verweis auf dieselben Wörterbücher haben, das Mitglied nicht statisch sein muss.

    
Adam Houldsworth 19.06.2012 15:43
quelle
0

Dies ist beabsichtigt. Ein statisches Member hat nur eine Kopie in allen Instanzen und ein statisches Member in einer Basisklasse hat nur eine Kopie in allen Instanzen aller Unterklassen.

Warum bist du statisch? Möchten Sie, dass alle Instanzen von One ein gemeinsames Wörterbuch gemeinsam verwenden?

Wenn Sie möchten, dass Einer über andere teilt, aber nicht mit Twos teilt, müssen Sie Ihr Design ändern. Machen Sie es entweder nicht statisch (was keine Freigabe verursacht) oder statisch auf der Ebene jeder Unterklasse.

Mache eine abstrakte Methode / Eigenschaft in der Basisklasse und überschreibe sie in den Unterklassen, wenn du die API zwischen ihnen halten möchtest

    
Jason Coyne 19.06.2012 15:34
quelle
0

Machen Sie Ihre Basis anders.

%Vor%

UPDATE: Nach der Veröffentlichung bemerkte ich mehr oder weniger die gleiche Antwort wurde bereits gegeben, aber beachten Sie den Unterschied: die Einschränkung für den Typ T und die Verwendung von T in der Wörterbuchdefinition. Es ist nicht dumm, aber es hilft.

Die Umwandlung in T muss das Objekt zum Wörterbuch hinzufügen können. Beachten Sie, dass ich eine explizite Umwandlung und nicht den Operator as verwende. Bei falscher Verwendung würde der Operator as eine Null in das Wörterbuch einfügen, wo der Cast ihn (wie es sollte) brechen sollte.

Aber auch: Ссылка

    
Kris Vandermotten 19.06.2012 15:32
quelle

Tags und Links