Erstellen einer virtuellen generischen Methode in C #

7

Ich habe einige Basisklassen wie folgt:

%Vor%

Jetzt habe ich eine Windows Forms-Basisklasse wie folgt:

%Vor%

und eine abgeleitete Form:

%Vor%

Das Problem ist, ich erhalte immer Kompilierfehler in der PersonForm-Klasse:

  

Der Typ 'PersonManager' kann nicht implizit in 'AbstractManager & lt; T & gt;'

konvertiert werden

Gibt es eine Möglichkeit, wie ich diese virtuelle Methode erstellen kann und jede von BaseForm abgeleitete Klasse die konkrete Darstellung des AbstractManagers liefert?

Wenn ich das generische Element in der AbstractManager-Klasse loslasse, kompiliere ich OK (mit ein paar Codeänderungen), aber dann kann die GetAll-Methode kein List<T> zurückgeben. Es müsste stattdessen ein List<AbstractData> zurückgegeben werden, was Probleme bei der Konvertierung von List<Person> nach List<AbstractData> verursacht.

Jede Hilfe wäre willkommen.

    
user3215491 20.01.2014, 14:48
quelle

2 Antworten

15

Zunächst einmal, bitte tu das nie:

%Vor%

Nun haben wir zwei Dinge namens T beide im Umfang und sie sind unterschiedlich. Das ist legal, aber sehr verwirrend. Wählen Sie bessere Namen für Ihre Typparameter.

Lassen Sie uns Ihr Beispiel vereinfachen:

%Vor%

Siehst du jetzt, warum das falsch ist? Was ist, wenn jemand C.GetBasket<Orange>() anruft und ihnen einen Korb Äpfel überreicht?

  

Jede Hilfe wäre willkommen.

Was ist der erste Schritt, um aus einem Loch zu kommen? STOP DIGGING .

Sie haben Genericity Happiness Disease, die C # -Programmierern gemein ist, die die Macht des generischen Typsystems entdecken und es dann für alles verwenden wollen, ob das sinnvoll ist oder nicht. Versuchen Sie nicht, alle Beziehungen in Ihrem Geschäftsprozess im generischen Typsystem zu erfassen. Dafür ist es nicht gedacht.

Der Test ist: Können Sie sagen "Ein Apfelkorb ist ein Korb mit Äpfeln, wo Äpfel eine Art Frucht sind" und jemand, der kein Programmierer ist, mit Ihnen einverstanden ist? Ja. Können Sie sagen: "Ein Person Manager ist ein abstrakter Manager von Personen, bei dem die Person eine Art abstrakter Daten ist" und jemand, der kein Programmierer ist, mit Ihnen einverstanden ist? Nein. Dann modellieren Sie die Geschäftsdomäne nicht erfolgreich im Typsystem . Beginne neu, vermeide Generika und versuche, Beziehungen zwischen Typen herzustellen, die Sinn ergeben.

    
Eric Lippert 20.01.2014 16:01
quelle
11

Indem Sie

deklarieren %Vor%

in BaseForm , versprechen Sie, dass jede Klasse, die von BaseForm abgeleitet ist, GetManager für any Typ T unterstützt. Wenn Sie beispielsweise eine andere AbstractData Unterklasse namens Invoice hätten, könnten Sie

schreiben %Vor%

und PersonForm würden einen InvoiceManager zurückgeben.

Wenn Sie möchten, dass jede von BaseForm abgeleitete Klasse GetManager nur für eins T unterstützt, dann verschieben Sie den Parameter T type von GetManager auf BaseForm :

%Vor%

UPDATE: Chad Henderson weist darauf hin, dass der Windows Forms-Designer keine generischen Basisklassen verarbeiten kann. Wenn das ein Problem für Sie ist, können Sie einen alternativen Ansatz versuchen:

%Vor%     
Michael Liu 20.01.2014 15:08
quelle

Tags und Links