2016-03-22 6 views
-1

Ich habe eine Zeichenfolge, die ich von einer Datenbank mit einem Klassennamen erhalte, zum Beispiel: "w_task1". Wenn ich den Skriptnamen von der Datenbank hole, weiß ich nicht, welches Skript es ist, also kann w_task1 t = new w_task1() nicht schreiben.Aufruf eines Klassendateinamens aus einer Zeichenfolge mit dem Klassennamen

Stattdessen will ich es nach dem Vorbild der (value of class name) t = new (value of class name)() sein.

Klassennamen, die ich öffnen möchte, variieren von: w_task1.cs - w_task25.

Ich habe versucht, das ganze mit:

Type type = Type.GetType("w_task1"); 
object o = Activator.CreateInstance(type); 

... Aber Typ ist gleich null, wenn das RAN des Programms.

Wie öffne ich die Klasse aus der Zeichenfolge, ohne den Klassentyp zu kennen?

+0

Sie öffnen nicht die Klasse wie in einer Datei öffnen. Sie laden eine Assembly und instanziieren eine Klasse anhand ihrer Informationen zum Laufzeittyp. C# ist nicht wie Python oder eine Skriptsprache. –

Antwort

1

Ihre Antwort ist hier: get assembly by class name

diese Frage von Marc GRA beantwortet

Sie müssen geladene Assembly von Ihrem Klassennamen finden (Linq helfen), dann kann die Reflexion Zeug rufen Sie Ihren Methode.

ich markiert Ihre Frage so dupliziert.

Sie können eine Klasse nicht über den Dateinamen öffnen. Wie kann Ihre CLR die Verbindung zwischen dem Dateinamen und der Klasse herstellen?

+0

War ewig alt, konnte das nicht finden. Vielen Dank! Eine letzte Frage, jetzt habe ich die Klasse instanziiert, wie rufe ich eine Funktion von innen heraus? –

+0

Zuerst bitte valide die Antwort :) Zweite Antwort direkt von Google: http://stackoverflow.com/questions/6472980/how-to-instantiate-the-class-in-an-assembly-using-reflection-with-c -net – pix

1

Sie müssen den vollständigen Namespace und Klassennamen zur Verfügung zu stellen.

würde ich wahrscheinlich so etwas wie diese (vorausgesetzt, dass der Namespace immer das gleiche ist und die Art wird in der gleichen Baugruppe gefunden) tun:

Assembly.GetExecutingAssembly().GetType("MyApp.Scripts." + my_string); 

Alternativ können Sie

  • speichert die Namespace zum DB
  • Suche nach allen Typen in Ihrer Versammlung (en) mit dem Namen und einige Schnittstelle und wahrscheinlich mehr Kriterien.
  • haben ein Wörterbuch, das Strings bekannten Namen zuordnet.

Betrachten Sicherheit: woher diese Daten stammen aus? Könnte ein Benutzer es irgendwie injizieren? Eine beliebige Klasse könnte geladen und wahrscheinlich ausgeführt werden.

würde ich eine Schnittstelle verwenden:

IScript o = (IScript)Activator.CreateInstance(type); 

sowohl die Verwendung von mehr Reflexion verringern und die Sicherheit verbessern.

+0

Danke, ich werde damit experimentieren! –

+0

Assembly.GetExecutingAssembly(). GetType (string.Format ("MyApp.Scripts. {0}", my_string)); IScript o = Activator.CreateInstance (Typ) als IScript; if (IScript! = Null) {doSomething} ist noch sauberer. – pix

+0

@pix: nicht unbedingt. Vergessen Sie bei der Verwendung des String-Formats nicht, Kulturinformationen anzugeben. Es ist sehr aufgebläht und unlesbar für so einfache Dinge. Wenn der Typ, bei dem der Typ die erwartete Schnittstelle nicht implementiert, tatsächlich ein Programmierfehler ist und nicht etwas, was der Benutzer falsch machen kann, würde ich eine type-Cast-Ausnahme erwarten, so dass keine spezielle Behandlung erforderlich ist. –