Laden...

[erledigt] vorhandene Klasse über den Namen(String) instantieren

Erstellt von falangkinjau vor 16 Jahren Letzter Beitrag vor 16 Jahren 2.017 Views
F
falangkinjau Themenstarter:in
171 Beiträge seit 2006
vor 16 Jahren
[erledigt] vorhandene Klasse über den Namen(String) instantieren

Hallo,

wie kann ich mit einem gegebenen String eine gleichnamige vorhandene Klasse instantieren.

Beispiel:
gegeben ist:


class foo 
{
    public foo();
}

und der String "foo".

Folgendes geht leider nicht, da bei typeof natürlich der Type angegeben werden soll.
So was in der Richtung wie unterer Psyeudocode muß es doch geben.


string klasse = "foo";
void SomeFunc(string klasse)
{
Type t = typeof(klasse)
ConstructorInfo ctor = t.GetConstructor();
Object o = ctor.Invoke();
}

Was habe ich übersehen bzw. gibt es da noch was anderes? Geht es überhaupt?

Gruß falangkinjau

2.223 Beiträge seit 2005
vor 16 Jahren

Hallo falangkinjau,

Ja das ganze ist auf jeden Fall möglich

unter dem Stichwort 'Reflection' wirst du entweder in der Literatur oder auch hier im Forum oder im Netz so einiges finden

bei weiteren Fragen zu diesem Thema kannst du natürlich gerne wieder Fragen

mfg

664 Beiträge seit 2005
vor 16 Jahren

Activator.CreateInstance (und Type.GetType )

F
falangkinjau Themenstarter:in
171 Beiträge seit 2006
vor 16 Jahren

Hallo langalaxy,

danke, genau die ist es.

Gruß falangkinjau

J
49 Beiträge seit 2007
vor 16 Jahren

ist zwar schon etwas älter....

aber ich hab die gleiche frage.

und irgendwie werd ich aus den anderen threads nicht schlau....

ich erzeuge mir ein objekt der klasse (glaube ich jedenfalls) mit


 object obj = new object();
            obj = Activator.CreateInstance(null ,"Projektname.Klassenname"); ;

diese klasse ist eine form.
was aber muss ich nun noch coden, damit ich ein

obj.show(); erreiche?

ich habs mit nem cast versucht


(obj as Form).show();

bekomme dann die fehlermeldung, dass der objektverweis nicht erzeugt ist
also NULL ist.

ist dieses objekt obj also nur eine art neuer typ, und muss ich irgendwie erst eine echte instanz davon erzeugen?

aber wie?

ich möchte irgendwie mit einem .show() meine form anzeigen lassen.....
wie? ^^

plz help
JL

2.187 Beiträge seit 2005
vor 16 Jahren

Guten Morgen,

System.Activator bietet viele Methoden an. Die, die du verwendet hast ObjectHandel CreateInstance(string,string), gibt nicht direkt das erstellte Objekt zurück, sonder eine Instanz vom Typ ObectHandel.

A) Du rufst die Methode "Unwrap()" von dem ObjectHandel auf, welche dir dein echtes Objekt zurück gibt oder
B) Du verwendest eine andere Methode von System.Activator. Folgende Methode würde ich empfehlen: object CreateInstance(System.Type,object[])

  • Sie verwendet einen System.Type zum erstellen deines Objekts
  • Sie gibt dein Objekt direkt zurück.

Type meineKlasse = Type.GetType("Namespace.Klassenname,AssemblyName");
// du solltest diech über Namespaces und AssemblyNamen schlau machen, du hast in deinem Post Projektname geschriebe, was nicht ganz richtig ist.
object meinObjekt = Activator.CreateInstance(meineKlasse,new object[0]);

Gruß
Juy Juka

1.820 Beiträge seit 2005
vor 16 Jahren

Hallo!

Unabhängig von JuyJuka's Beitrag noch ein Hinweis: Wenn obj null ist, dann konnte Activator.CreateInstanz keine Instanz erzeugen (z.B. weil der Name falsch ist) und gibt null zurück.

Man sollte bei solchen Methoden also immer zusätzlich prüfen, ob der Rückgabewert evtl. null ist.

EDIT: OK, eigentlich sollte man IMMER prüfen, ob ein Rückgabewert korrekt ist 😁

Nobody is perfect. I'm sad, i'm not nobody 🙁

4.506 Beiträge seit 2004
vor 16 Jahren

Hallo zusammen,

ich wollte hier mal einen Tipp in eine andere Richtung geben. Eventuell kann man hier auf Reflection verzichten und auf eine Abstrakte Fabrik (Abstract Factory Pattern) zurückgreifen, meistens ist das ausreichend.

Wenn nicht, dann kann man sich hier auch das IOC (Inversion of Control) Pattern anschauen, das einem ermöglicht über Interfaces maskiert verschiedene Instanzen zu erzeugen und zu ermitteln ohne auf Typsicherheit und Intellisense zu verzichten.

Reflection ist meiner Meinung nach meistens zu unkomfortabel, was Programmierung angeht, und wehe dem, wenn sich etwas an dem Instanziierten Objekt designtechnisch etwas ändert, dann heißt das in X-Stellen im Code anpassen (überall, wo mit dem Reflector-Objekt gearbeitet wird).

Deshalb vermeide ich Reflection wo es geht.

Grüße
Norman-Timo

A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”

J
49 Beiträge seit 2007
vor 16 Jahren

Type meineKlasse = Type.GetType("Namespace.Klassenname,AssemblyName");
// du solltest diech über Namespaces und AssemblyNamen schlau machen, du hast in deinem Post Projektname geschriebe, was nicht ganz richtig ist.
object meinObjekt = Activator.CreateInstance(meineKlasse,new object[0]);

das hat mir soweit sehr gut geholfen, allerdings muss da wohl n fehler in deine post sein.
Type meineKlasse = Type.GetType("Namespace.Klassenname,AssemblyName");
das wäre ein string, durch komma getrennt - irgendwie.....

ist das so korrekt?
weil ich habe einfach,


Projektname.Formname 
genommen.

und der Projektname ist in meinem fall auch der namespace wo die zu verwendende Form liegt.

danach kann ich das objekt einfach in FORM casten und mit 
(...).show(); 
aufrufen.

somit ist glaub ich erstmal alles funktionsfähig.

besten dank soweit :)

JL
J
3.331 Beiträge seit 2006
vor 16 Jahren

Hallo,

  
Type meineKlasse = Type.GetType("Namespace.Klassenname,AssemblyName");  
// du solltest diech über Namespaces und AssemblyNamen schlau machen, du hast in deinem Post Projektname geschriebe, was nicht ganz richtig ist.  
object meinObjekt = Activator.CreateInstance(meineKlasse,new object[0]);  

das hat mir soweit sehr gut geholfen, allerdings muss da wohl n fehler in deine post sein.

Das könnte sein; vermutlich hat sich JuyJuka beim Kopieren vertan. Das kann aber jeder selbst in der :rtfm: prüfen:

Für Type.GetType() gibt es keine Überladung, die den Namen der Assembly benutzt.

Für Activator.CreateInstance gibt es eine Überladung mit AssemblyName, TypeName, Object[].

Es sollte also problemlos möglich sein, das zu ändern.

ich habe einfach Projektname.Formname genommen. und der Projektname ist in meinem fall auch der namespace wo die zu verwendende Form liegt.

Diese Kombination "Projektname.Formname" ist gängige Praxis; dennoch musst Du unterscheiden: die String-Inhalte sind möglicherweise gleich, aber Projekt(name) und Namespace sind trotzdem zwei ganz verschiedene Sachen.

Jürgen

J
49 Beiträge seit 2007
vor 16 Jahren

ja ok, dass der Projektname nicht mit dem namespace übereinstimmen muss, ist klar.
bei mir wars nur eben so...deswegen dachte ich anfangs, ich müsste den projektnamen verwenden. mein fehler....

habs nun nochmal ordentlicher geschrieben



  Type type_MyTempType = Type.GetType(NameSpace.Formname(Klassename);

//das hier hab ich anfangs nicht verstanden, es ist aber quasi die liste,
//die man dem konstruktor übergibt  
object[] MyTempParameterObject = new object[1];
  MyTempParameterObject[0] = new_OpenFileDialog.FileName;

   object obj_MyTempObject = Activator.CreateInstance(type_MyTempType, MyTempParameterObject);
                (obj_MyTempObject as Form).MdiParent = this;
                (obj_MyTempObject as Form).Show();


also in meinem fall übergebe ich der Form einen String, der die zu ladende Datei repräsentiert.

wollte mal loswerden, wofür das übergeben object-Array ist 🙂
vll ist ja noch jemand davon etwas verwirrt gewesen.

thx und so 🙂

JL

2.187 Beiträge seit 2005
vor 16 Jahren

Hallo,

Jemand hat gefragt, ob das Komma in meinem string, den ich an System.Type.GetType übergebe ein Fehler war. Nein ist er nicht. Wenn an den FullQalifiedName des Typs mit Komma noch der Name des Assemblies angehängt wird, ist das der AssemblyQalifiedName!
Mit dem AssemlbyQalifiedName kann man auch Typen aus einem nicht Referenzierten Assembly laden.
Außerdem hat man mit dem AssemblyQalifiedName meistens weniger Probleme mit der Assembly-Verwaltung von .NET (weil man nicht rein greift und was kaput macht).

Gruß
Juy Juka

J
3.331 Beiträge seit 2006
vor 16 Jahren

Hallo JuyJuka,

danke für diese Klarstellung und Entschuldigung für meine vorige Vermutung, Du hättest Dich vertan. Da finde ich mich inzwischen in der SDK-Doku so gut zurecht, aber solche Unterschiede wie zwischen Name, FullName, AssemblyQalifiedName und deren Möglichkeiten sind mir doch noch durchgerutscht. Jürgen

2.187 Beiträge seit 2005
vor 16 Jahren

Hallo juetho,

Alles kein Thema, gibt keinen Grund sich zu entschuldigen.

Gruß
Juy Juka