Wie können Sie in einen Typ mit dem Typnamen als String umwandeln?

7

Ok, ich habe den ganzen Tag auf diese Idee geklopft, und ich habe den Teil erreicht, wo ich zugeben muss, dass ich es einfach nicht weiß. Es ist möglich, dass das, was ich tue, nur dumm ist und es gibt einen besseren Weg, aber das ist es, wo mich mein Denken gebracht hat.

Ich versuche, eine generische Methode zu verwenden, um Formulare in WinForms zu laden:

%Vor%

Die Formulare werden von einem ToolStripMenuItem geladen (entweder über die Auswahl des Elements oder über den Menüeintrag Open Windows). Sie sind Lazy-Loaded, daher gibt es Felder für die Formulare innerhalb des übergeordneten MDI, aber sie sind null, bis sie benötigt werden. Ich verwende eine gemeinsame Methode für ToolStripMenuItem_Click, die alle Menüelementklicks behandelt. Die Methode hat keine wirkliche Möglichkeit zu wissen, welche Form aufgerufen wird, außer dass der Name des ToolStripMenuItem mit einem Muster übereinstimmt, das für die Formklassennamen ausgewählt wurde, denen sie entsprechen. Mit dem Namen des ToolStripMenuItem kann ich also den Namen des angeforderten Typs des Formulars und den Namen des privaten Feldes erkennen, das zugewiesen wurde, um den Verweis für dieses Formular zu speichern.

Damit kann ich entweder eine wachsende / contracting switch-Anweisung mit hartcodierten Typen und String-Übereinstimmungen verwenden, um die Methode mit dem bestimmten Typsatz aufzurufen (unerwünscht), oder ich kann Reflection verwenden, um das Feld zu erhalten und die Instanz von zu erstellen der Typ. Das Problem ist, dass System.Activator.CreateInstance einen ObjectHandler bereitstellt, der nicht in die benötigten Typen umgewandelt werden kann. Hier ist ein Ausschnitt von dem, was ich bisher habe:

%Vor%

Ich kenne den String-Namen des Typs, der für (????) geht, aber zur Kompilierzeit kenne ich den Typ nicht, weil er sich ändert. Ich habe eine Reihe von Möglichkeiten ausprobiert, um diese Umwandlung / Instanziierung zum Laufen zu bringen, aber keine war erfolgreich. Ich würde sehr gerne wissen, ob es möglich ist, eine solche Besetzung durchzuführen, wenn man den Typ nur als String kennt. Ich habe versucht, mit Type.GetType(string, string) die Besetzung durchzuführen, aber der Compiler mochte es nicht. Wenn jemand eine andere Idee hat, wie man die Formulare dynamisch lädt, weil ich es nur dumm mache, lass es mich wissen.

    
Joel Etherton 28.01.2011, 19:10
quelle

4 Antworten

5

Sie wären besser dran mit der anderen Überladung , die ein Type und mit z Type.GetType(string) .

%Vor%     
Andras Vass 28.01.2011, 19:20
quelle
12

Dieses Problem wird normalerweise gelöst, indem auf eine gemeinsame Basisklasse oder Schnittstelle aller potenziellen Typen umgestellt wird.

In C # 4 können Sie es auch einer Variable dynamic zuweisen, um den Rückgabewert zu speichern und beliebige Methoden aufzurufen. Die Methoden werden spät gebunden sein. Ich bleibe jedoch lieber bei der ersten Lösung, wann immer es möglich ist.

    
Mehrdad Afshari 28.01.2011 19:14
quelle
2

Je nach dem, was Sie haben, muss FormWithWorker (mindestens) als Basisklasse des Typs sein, den Sie instanziieren, also können Sie dies tun:

%Vor%     
Mark Avenius 28.01.2011 19:16
quelle
0

Während eine gemeinsame Schnittstelle eine Möglichkeit ist, dieses Problem anzugehen, sind Schnittstellen für alle Szenarien nicht praktikabel. Die obige Entscheidung ist eine mit einem Fabrikmuster (Schalteranweisung - konkrete Klassenauswahl) oder Verwendung von Reflexion. Es gibt einen Stack-Post, der dieses Problem löst. Ich glaube, Sie können dies direkt auf Ihr Problem anwenden:

Method Factory - Fall vs. Reflexion

    
P.Brian.Mackey 28.01.2011 19:18
quelle

Tags und Links