Fabrik Erstellen von Objekten nach einem generischen Typ C #

7

Was wäre der effizienteste Weg, um ein Objekt nach einem generischen Typ zu instanziieren, der an eine Factory-Klasse übergeben wird, zum Beispiel:

%Vor%

Wie würdest du das machen? Welche Verzweigungs-Anweisung ? usw. ...

    
maxbeaudoin 17.07.2009, 18:05
quelle

8 Antworten

18

Ich denke, es ist am besten, es einfach zu halten, vielleicht in etwa so:

%Vor%

Sie rufen einfach AddLoggerProvider für jeden Typ auf, den Sie unterstützen möchten, können zur Laufzeit erweitert werden, es stellt sicher, dass Sie der Bibliothek eine Implementierung der Schnittstelle hinzufügen und nicht irgendein Objekt, das nicht sehr schnell ist Activator , aber das Erstellen eines Loggers wird sowieso wahrscheinlich kein Engpass sein. Hoffe, es sieht gut aus.

Verwendung:

%Vor%

Hinweis: Jedes ILogger<T> benötigt einen parameterlosen Konstruktor für Activator , aber auch das ist mit der generischen code new() in der add-Methode sichergestellt.

    
Kenan E. K. 17.07.2009, 20:55
quelle
6

Ich denke, ich würde es so machen:

%Vor%

Sie zahlen etwas von einem Lesbarkeitspreis (all diese spitzen Klammern, sheesh), aber wie Sie sehen können, macht es sehr wenig Programmlogik.

    
Robert Rossney 17.07.2009 20:12
quelle
4

Obwohl ich normalerweise die Verwendung eines Dependency-Injection-Frameworks empfehlen würde, könnten Sie etwas mit Reflection implementieren, das die verfügbaren Typen nach einem Typ durchsucht, der die entsprechende ILogger-Schnittstelle implementiert.

Ich würde vorschlagen, dass Sie sorgfältig überlegen, welche Assemblies diese Loggerimplementierungen enthalten und wie erweiterbar und kugelsicher die Lösung sein soll. Das Ausführen von Runtime-Suchen über die verfügbaren Assemblys und Typen hinweg ist nicht kostengünstig. Es ist jedoch eine einfache Möglichkeit, die Erweiterbarkeit in dieser Art von Design zu ermöglichen. Es vermeidet auch das Problem der Vorkonfiguration - es erfordert jedoch, dass nur ein konkreter Typ eine bestimmte Version des ILogger & lt; & gt; Schnittstelle - sonst gibt es eine mehrdeutige Situation, die Sie auflösen müssen.

Möglicherweise möchten Sie ein internes Caching durchführen, um die Kosten für die Reflektion bei jedem Aufruf von Create () zu vermeiden.

Hier ist ein Beispielcode, mit dem Sie anfangen könnten.

%Vor%     
LBushkin 17.07.2009 19:29
quelle
2

Hängt davon ab, mit wie vielen Typen Sie arbeiten möchten. Wenn es klein ist (weniger als 10), würde ich eine switch-Anweisung vorschlagen, da es schnell und sauberer zu lesen ist. Wenn Sie mehr wollen, sollten Sie eine Nachschlagetabelle (Hash Map, Dictionary, etc) oder ein auf Reflektion basierendes System verwenden.

    
C. Ross 17.07.2009 18:15
quelle
1

switch statement vs dictionary - spielt für die Performance keine Rolle, da ein Switch in ein Dictionary übersetzt wird. Es geht also wirklich um Lesbarkeit und Flexibilität. Der Schalter ist einfacher zu lesen, auf der anderen Seite kann ein Wörterbuch zur Laufzeit erweitert werden.

    
Scott Weinstein 17.07.2009 18:22
quelle
1

Sie könnten ein Framework zur Abhängigkeitsinjektion wie Unity in Erwägung ziehen. Sie können es mit den generischen Typen konfigurieren, die von Ihrem Faktor zurückgegeben werden, und die Zuordnung in der Konfiguration vornehmen. Hier ist ein Beispiel dafür .

    
JP Alioto 17.07.2009 18:39
quelle
1

1) Ich bin immer wieder erstaunt über die Komplexität, die Menschen beim Holzeinschlag haben. Für mich scheint es immer wie ein Overkill zu sein. Wenn log4net opensource ist, würde ich Ihnen empfehlen, sich das anzusehen, in der Tat, Sie könnten es genauso gut benutzen ...

2) Ich versuche, wenn immer möglich, eine Typprüfung zu vermeiden, da sie den Punkt der Generika besiegt. Verwenden Sie einfach die .ToString () -Methode und machen Sie damit fertig.

    
Leroy 17.07.2009 20:50
quelle
0

Hrm ... du könntest versuchen, etwas schlauer zu werden, je nachdem, was das gegebene Laufzeitsystem unterstützt. Ich versuche tatsächlich, bedingte Anweisungen in meinem Code zu vermeiden, vor allem in polymorphem und dynamisch gebundenem Code. Du hast dort eine generische Klasse, also warum nicht benutzen?

In Java können Sie beispielsweise die statische Methode, die Sie dort haben, besonders nutzen:

%Vor%

Sie würden es so nennen:

%Vor%

Dies vermeidet die Notwendigkeit, irgendwelche Bedingungen zu haben und ist außerdem flexibler: jede Klasse, die eine Unterklasse (oder implementiert die Logger-Schnittstelle, vielleicht) von SomeUsefulClass ist, kann die korrekt getippte Logger-Instanz zurückgeben.

    
Omar Zakaria 17.07.2009 19:11
quelle

Tags und Links