Laden...

Objekt aus Text erzeugen

Erstellt von andyp17 vor 13 Jahren Letzter Beitrag vor 13 Jahren 3.081 Views
A
andyp17 Themenstarter:in
12 Beiträge seit 2011
vor 13 Jahren
Objekt aus Text erzeugen

Hallo,
Ich schreibe ein Programm, das eine Menüleiste mit mehreren Unterpunkten hat. Jeder dieser Auswahlmöglichkeiten öffnet ein neues Fenster (frmTable). Diese Form ist für jede Auswahlmöglichkeit die gleiche - nur wird je nach Menüpunkt ein anderes Objekt in frmTable instanziiert. Doch wie mach ich das am elegantesten? Meine Idee war nun in der Tag-Eigenschaft jedes Menüpunkts den Namen des aufzurufenden Objekts zu übergeben (z.B. "TableUser"). Und aus diesem Namen "TableUser" soll dann eine Instanz der Klasse TableUser erstellt werden. Wie geht das?
Ich hoffe ihr wisst, was ich meine... 😃

Danke!

1.044 Beiträge seit 2008
vor 13 Jahren

Hallo andyp17,

so wie du es machst, ist es schlecht, sehr schlecht. Warum prüfst du die Eingabe bzw. den string mit mit einer if-Abfrage und entscheidest, ob eine Instanz erstellt werden soll? Falls du wirklich aus einem String ein Objekt erzeugen möchtet: Activator.CreateInstance.

zero_x

A
andyp17 Themenstarter:in
12 Beiträge seit 2011
vor 13 Jahren

Hallo,
Danke für die Antwort. Ich dachte mir nur, ich gestalte das Ganze generisch, sodass ich nicht immer, wenn ein neuer Menüpunkt hinzukommt, einen neuen else-Zweig bzw. einen neuen case-Zweig hinzufügen muss...

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo andyp17,

mit Strings ist das so eine Sache, weil die ja inhaltlich nicht vom Compiler geprüft werden. Merkte dir lieber den Typ (Type) des Objekts im Tag. Also z.B. typeof (TableUser). Da greift zumindest die Prüfung, ob der Typ existiert. Es gibt auch eine Activator.CreateInstance Überladung, die Type als Parameter bekommt.

Ansonsten finde ich dein Vorgehen ok.

herbivore

F
10.010 Beiträge seit 2004
vor 13 Jahren

Ansonsten finde ich dein Vorgehen ok.

Und ich finde diesen Versuch alles zu generalisieren nicht OK.
Alles generalisieren zu wollen ist selten vernünftig wartbar.

Warum es nicht so machen wie es vorgesehen ist?
Einen Menüpunkt aufrufen und dort dann eben die entsprechende Bearbeitung machen, und zwar für jeden Menüpunkt einzeln.

Auch zeugt ein frmTable und das benutzen von Tag eher von einer VB6 Vergangenheit.
Und zu 99% ist das herüberretten von VB6 Herangehensweisen alles andere als vernünftig.

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo FZelle,

es ist doch sinnvoll, an den Stellen, wo es geht, deklarativ zu programmieren. Du benutzt doch auch DataBinding und überträgst die Daten nicht von Hand in die Controls und zurück. Das hier ist vollkommen analog. Man deklariert durch die Zuweisung des Typs an MenuItem.Tag nur, welches Form erzeugt werden soll, und den Rest überlässt man der Infrastruktur. Das dahinter steckende Konzept ist DRY. Man kann also sagen: das Vorgehen ist nicht nur ok, sondern sogar geboten.

herbivore

A
andyp17 Themenstarter:in
12 Beiträge seit 2011
vor 13 Jahren

Hallo nochmals,

Eigentlich müsste es doch so gehen, oder:


var t = Type.GetType(type);
var test = Activator.CreateInstance(t);

Aber er schreibt dauernd: Der Wert darf nicht NULL sein. (t ist null) - warum das?

Andere Frage: Je nach geklicktem Menüpunkt soll doch ein anderes Objekt instanziiert werden. Dieses soll aber innerhalb der gesamten Klasse frmTable nutzbar sein. Wenn ich jetzt aber im Konstruktor ein spezifisches Objekt anlege, ist das doch nur innerhalb dieser Methode gültig. Daher müsste ich global (in der Klasse) eine Variable von jedem Typen anlegen und erst im Konstruktor das tatsächliche Objekt instanziieren, oder? Wenn ich aber bspw. 15 verschiedene Objekte habe, muss ich 15 Variablen anlegen, obwohl ich dann aber nur einen Typ brauche. Könnte ich nicht z.B. EINE Variable vom Typ "Object" anlegen und der dann aber das benötigte Objekt so zuweisen, dass ich in der ganzen Klasse frmTable auf dessen Methoden zugreifen kann (sozusagen casten)?
Ich hoffe, ich konnte mich verständlich ausdrücken.. 😃

lg

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo andyp17,

verwende nicht Type.GetType, sondern typeof.

herbivore

F
10.010 Beiträge seit 2004
vor 13 Jahren

@herbivore:
Sehe ich anders.
DRY bedeutet das man OOP verstehen und nach Möglichkeit Muster als solche erkennen sollte und diese dann mit den Mitteln der OOP vereinfacht.

Tag zu benutzen zeigt aber eher das hier OOP nicht angedacht ist, und der OP zeigt mit seinem Unverständnis auch, das hier kein Plan vorliegt.

Und das hat überhaupt nichts mit DataBinding zu tun.

Aber mit dir zu diskutieren hat ja eh keinen sinn, weshalb ich mich ab hier ausklinke

A
andyp17 Themenstarter:in
12 Beiträge seit 2011
vor 13 Jahren

typeof funktioniert da nicht, weil ja der Parameter vom Typ string ist....

2.891 Beiträge seit 2004
vor 13 Jahren

typeof funktioniert da nicht, weil ja der Parameter vom Typ string ist....

Du musst die Type.GetType(String)-Methode nehmen.
Und falls du null zurück bekommst, bitte beachte folgendes (einfach nur der Klassenname reicht nicht, du brauchst mindestens den Namespace mit dazu):

Zitat von: AssemblyQualifiedName
typeName
Typ: System.String
Der durch die Assembly bezeichnete Name des abzurufenden Typs.Siehe AssemblyQualifiedName.Wenn sich der Typ in der aktuell ausgeführten Assembly oder in Mscorlib.dll befindet, ist eine Angabe des Typnamens einschließlich des qualifizierenden Namespace ausreichend.

Gruß,
dN!3L

Gelöschter Account
vor 13 Jahren

typeof funktioniert da nicht, weil ja der Parameter vom Typ string ist....

Du sollst ja nicht string nehmen, sondern eben den Typen. Vergiss das mit den string, das ist echt mieser Stiel.

@dN!3L:
Das wäre jetzt von hinten durch die Brust... 😃

A
andyp17 Themenstarter:in
12 Beiträge seit 2011
vor 13 Jahren

OK, hab die Idee mit dem string jetzt verworfen - hat mir dann auch nicht so gut gefallen. Jedoch bräuchte ich jetzt eine Antwort auf meine andere Frage:

Andere Frage: Je nach geklicktem Menüpunkt soll doch ein anderes Objekt instanziiert werden. Dieses soll aber innerhalb der gesamten Klasse frmTable nutzbar sein. Wenn ich jetzt aber im Konstruktor ein spezifisches Objekt anlege, ist das doch nur innerhalb dieser Methode gültig. Daher müsste ich global (in der Klasse) eine Variable von jedem Typen anlegen und erst im Konstruktor das tatsächliche Objekt instanziieren, oder? Wenn ich aber bspw. 15 verschiedene Objekte habe, muss ich 15 Variablen anlegen, obwohl ich dann aber nur einen Typ brauche. Könnte ich nicht z.B. EINE Variable vom Typ "Object" anlegen und der dann aber das benötigte Objekt so zuweisen, dass ich in der ganzen Klasse frmTable auf dessen Methoden zugreifen kann (sozusagen casten)?
Ich hoffe, ich konnte mich verständlich ausdrücken.. 😃

Vielen Dank!