Instanz des generischen Typs erstellen?
Wenn BaseFruit
hat einen Konstruktor akzeptiert ein int weight
können instanziiere ich ein Stück Obst in eine generische Methode wie diese?
public void AddFruit<T>()where T: BaseFruit{
BaseFruit fruit = new T(weight); /*new Apple(150);*/
fruit.Enlist(fruitManager);
}
Wurde ein Beispiel Hinzugefügt, die hinter die Kommentare. Es scheint, ich kann dies nur tun, wenn ich BaseFruit
einen parameterlosen Konstruktor und füllen Sie dann alles über member-Variablen. In meinem wirklichen code (nicht etwa die Früchte), diese ist eher unpraktisch.
-Update-
So scheint es, es nicht gelöst werden kann, indem Sie Einschränkungen in irgendeiner Art und Weise dann. Aus den Antworten gibt es drei Kandidaten-Lösungen:
- Fabrik-Muster
- Reflexion
- Aktivator
Ich dazu neigen zu denken, die Reflexion, ist das zumindest sauber, aber ich kann mich nicht entscheiden zwischen den beiden anderen.
InformationsquelleAutor der Frage Boris Callens | 2009-04-08
Du musst angemeldet sein, um einen Kommentar abzugeben.
Zusätzlich ein einfacheres Beispiel:
Beachten Sie, dass mit der new () - Einschränkung auf T ist nur, damit der compiler überprüfen Sie für einen öffentlichen parameterlosen Konstruktor zur compile-Zeit, den eigentlichen code zum erstellen der Typ ist der Activator-Klasse.
Vergewissern Sie sich über die spezifischen Konstruktor bestehenden, und diese Art der Anforderung kann ein code, der Geruch (oder eher etwas, sollte man einfach versuchen zu vermeiden, in der aktuellen version auf c#).
InformationsquelleAutor der Antwort meandmycode
Können Sie nicht alle parametrierten Konstruktor. Sie können einen parameterlosen Konstruktor haben, wenn Sie einen "
where T : new()
" - Einschränkung.Es ist ein Schmerz, aber so ist das Leben 🙁
Dies ist eines der Dinge, die ich möchte zu einer Adresse mit "static interfaces". Sie würden dann in der Lage sein, für die Eindämmung von T enthalten statische Methoden, Operatoren und Konstruktoren, und dann rufen Sie.
InformationsquelleAutor der Antwort Jon Skeet
Ja; ändern Sie Ihre wo werden:
Allerdings funktioniert dies nur mit parameterlosen Konstruktoren. Du musst eine andere Möglichkeit der Einstellung der Eigenschaft (wenn Sie die Immobilie selbst oder etwas ähnliches).
InformationsquelleAutor der Antwort Adam Robinson
Einfachste Lösung
Activator.CreateInstance<T>()
InformationsquelleAutor der Antwort user1471935
Wie Jon darauf hingewiesen, das ist das Leben für beeinträchtige ein nicht parameterlosen Konstruktor. Aber eine andere Lösung ist die Verwendung eines factory-pattern. Dies ist leicht constrainable haben
Doch eine andere option ist die Verwendung eines funktionalen Ansatzes. Pass in eine factory-Methode.
InformationsquelleAutor der Antwort JaredPar
Die Sie tun können, mit Reflexion:
EDIT: - Hinzugefügt Konstruktor == null überprüfen.
EDIT: Eine schnellere Variante, ein cache:
InformationsquelleAutor der Antwort mmmmmmmm
Kürzlich stieß ich auf ein sehr ähnliches problem. Wollte nur zu teilen, die unsere Lösung mit Ihnen allen. Ich wollte erstellte ich eine Instanz einer
Car<CarA>
aus einem json-Objekt, mit dem hatte eine enum:InformationsquelleAutor der Antwort farshid
Ist es noch möglich, mit hoher Leistung, indem Sie den folgenden tun:
und
Den relevanten Klassen haben dann die Ableitung von dieser Schnittstelle und initialisiert sich entsprechend.
Bitte beachten Sie, dass in meinem Fall, dieser code ist Teil einer umgebenden Klasse, die <T> als generische parameter.
R, in meinem Fall, auch ist eine nur-lese-Klasse. IMO, die öffentliche Verfügbarkeit der Initialize () - Funktionen keine negativen Auswirkungen auf die Unveränderlichkeit. Der Benutzer dieser Klasse setzen könnte, ein anderes Objekt, aber das würde nicht ändern, die zugrunde liegende Sammlung.
InformationsquelleAutor der Antwort cskwg