Laden...

Casting zu ursprüglichem Typ?

Erstellt von Hank-ER vor 18 Jahren Letzter Beitrag vor 18 Jahren 1.119 Views
H
Hank-ER Themenstarter:in
16 Beiträge seit 2005
vor 18 Jahren
Casting zu ursprüglichem Typ?

Hallo,

ich bin recht neu in C#, also nicht gleich hauen, wenn mal was keinen Sinn ergibt...

Kann man in C# ein Objekt einer Klasse aus einer Assembly liefern lassen und dieses dann in den ursprünglichen Typ zurückcasten?

Was ich machen wollte ist folgendes: Aus einer Assembly, die zur Laufzeit erst bekannt wird, soll ein UserInterface (genauer: Eine Klasse, die von UserControl erbt) in die aktuell laufende Anwendung integriert werden.

public void InvokeMethode(string assembly, string type, string methode, object[] parameters)
		{
			// Create object from assembly
			Assembly myAssembly = System.Reflection.Assembly.LoadFrom(assembly);
			object myObj = myAssembly.CreateInstance(type);

			// Invode methode
			Type myTypea = myObj.GetType();
			MethodInfo myMethodinfoa = myTypea.GetMethod(methode);
			object myObj2 =	myMethodinfoa.Invoke(myObj, parameters);
			Type myTypeb = myObj2.GetType();

			Console.WriteLine(myObj2.ToString());
			Console.WriteLine(myTypeb.ToString());
			//MessageBox.Show(myObj2);
			[B]System.Windows.Forms.UserControl uc = (System.Windows.Forms.UserControl)myObj2;[/B]
			testTab = new System.Windows.Forms.TabPage();

			testTab.Controls.Add(uc);
			tabControl1.Controls.Add(testTab);

			


		}

Wie man sieht, konnte ich das Objekt nur auf UserControl casten, das wäre natürlich fatal...

P
939 Beiträge seit 2003
vor 18 Jahren

Hi Hank-ER,

warum kann nur nach UserControl gecasted werden?
Oder, warum geht das nicht:

object myObj2 = // ...;
MyUserControl myUserControl = (MyUserControl)myObj2;

Falls du mehrere unabhängige UserControl-Klassen geschrieben hast, in die myObj2 gecastet werden können soll, gibt es verschiedene Möglichkeiten, hier zwei Stück:

1: alle UserControls leiten von einem abstrakten Basis-UserControl ab, das alle benötigten Methoden und Eigenschaften abstrakt vordefiniert (Alternativ können die UserControls auch ein gemeinsames Interface implementieren):

public class MyUserControlBase : UserControl {
   public abstract int Value1 { get; set; }
}

public class MyUserControlA : MyUserControlBase {
  public override int Value1 { /* Impl.; */ }
}

public class MyUserControlB : MyUserControlBase {
  public override int Value1 { /* Impl.; */ }
}

2: Du testest mit dem is-Operator auf den konkreten Type.

object myObj2;

if(myObj2 is MyUserControlA) {
  MyUserControlA a = (MyUserControlA)myObj2;

} else if(myObj2 is MyUserControlB) {
  MyUserControlB b = (MyUserControlA)myObj2;
}

Gruss
Pulpapex

H
Hank-ER Themenstarter:in
16 Beiträge seit 2005
vor 18 Jahren

Danke für die schnelle Antwort. Das Problem ist nur, dass ich den Typ, in den ich casten will zur Compile-Zeit nicht kenne. Mit getType bekomme ich ihn ja...

P
939 Beiträge seit 2003
vor 18 Jahren

mit GetType bekommst du ein Type-Objekt. Das ist nicht der eigentliche Type, sondern nur eine Repräsentation in Objektform.

Über Type-Objekte ist Reflection möglich. Theoretisch liesse sich mit Reflection alles dynamisch zur Laufzeit machen, was man sonst starr im Quellcode programmiert. Das wäre also eine Lösung wie man unbekannte Typen verwenden kann.

Allerdings eine sehr schlechte Lösung. Durch Reflection verliert man die Typsicherheit, der Code wird unleserlich, schwerer wartbar und langsamer. Wenn möglich, Reflection immer vermeiden.

Die allermeisten Probleme lassen sich auch so lösen. In deinem Fall reicht es wie gesagt z.B. aus, ein Interface vorzugeben, das alle UserControls implementieren müssen, damit sie dynamisch zur Laufzeit geladen und verwendet werden können.

H
Hank-ER Themenstarter:in
16 Beiträge seit 2005
vor 18 Jahren

Ok, danke, habe jetzt so halbwegs verstanden denke ich -
trotzdem nochmal zum tieferen Verständnis:
In der Anwendung sollen frei definierbare UserControls hinzuladbar sein.
Letztendlich soll es sich um UserControls handeln, die einfach in einen Reiter eingefügt werden. Das heißt es werden keine Methoden diese UserControls "von außen" aufgerufen , denn jedes davon funktioniert gewissermaßen als eigenständige Anwendung.
Um die Controls in den Reiter schmeißen zu können, muss ich sie für die Hauptanwenung ja irgendwie hochcasten (ein bloßes object kann ich ja nicht in einen Reiter einfügen).
Kann es sein, dass ich jetzt gar nichts weiter tun muss, damit die Sache funktioniert? - Mal abgesehen von schlechtem Stil...

P
939 Beiträge seit 2003
vor 18 Jahren

Genauso ist es,

der Cast nach UserControl reicht in dem Fall vollkommen aus (... ist auch kein schlechter Stil, oder was meintest du?).

Deine Anwendung sollte bei den UserControls vielleicht noch DockStyle.Fill setzen, damit diese immer die gesamte TabPage ausfüllen.