Laden...

Dynamische Properties zur Laufzeit?

Erstellt von roland vor 18 Jahren Letzter Beitrag vor 18 Jahren 3.389 Views
roland Themenstarter:in
257 Beiträge seit 2004
vor 18 Jahren
Dynamische Properties zur Laufzeit?

Hallo c#pler,

ist es möglich einer Klasse zur Laufzeit neue Properties hinzuzufügen?

Es geht darum, das ein Benutzer zusätzliche Felder zu bestimmten Objekten konfigurieren kann.

Hierbei darf es sich nicht um eine Collection oder Array handeln, um zusätzliche Felder zu verwalten, sondern um echte Properties.

Wenn das geht wäre ich für eine Beschreibung der Lösung sehr dankbar.

Viele Grüße

roland

2.921 Beiträge seit 2005
vor 18 Jahren

Also eigentlich bleiben Dir dann nur zwei Möglichkeiten übrig, entweder doch eine ArrayList zu verwenden, oder das ganze per Reflection zu machen.

Hier ein Ansatz für eine Liste:


	public class CONTROLSTATE
	{
		private string m_sControlState = null;

		public CONTROLSTATE(string sControlState)
		{
			m_sControlState = sControlState;
		}

		public CONTROLSTATE()
		{
		}

		public override string ToString()
		{
			return m_sControlState;
		}
	}


		private void AddProps(SortedList sl)
		{
			CONTROLSTATE[] ctrlStates = CONTROLSTATES.SINGLETON.STATES;
			for(int i=0;i<ctrlStates.GetLength(0);i++)
			{
				//sl.Add(ctrlStates[i],null);
				sl.Add(ctrlStates[i].ToString(),null);
			}
		}

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

2.921 Beiträge seit 2005
vor 18 Jahren

Ich rufe die Properties dann so auf:


SkinnedControl ctrl = SkinControlsProxy.SKINCONTROLSPROXY.GetSkinnedControl(typeof(Form));

			CONTROLSTATE[] STATE = CONTROLSTATES.SINGLETON.STATES;
			/*for(int i=0;i<SkinControlsProxy.SKINCONTROLSPROXY.Count;i++)
			{
				//this part has to be changed in future because it is not runtime expendable!!!!
				//STATE[i]: this might be a string in ctrl.Properties, if Icomparer does cause an exception
				for(int j=0;j<CONTROLSTATES.SINGLETON.STATES.GetLength(0);i++)
				{
					ctrl.Properties.SetBackgroundImage	(STATE[i],	(Image)m_slImgBackground[STATE[i]]);
					ctrl.Properties.SetBackColor		(STATE[i],	(Color)m_slBackColor[STATE[i]]);
					ctrl.Properties.SetForeColor		(STATE[i],	(Color)m_slForeColor[STATE[i]]);
					ctrl.Properties.SetFont				(STATE[i],	(Font)m_slFont[STATE[i]]);
					ctrl.Properties.SetImage			(STATE[i],	(Image)m_slImage[STATE[i]]);
					ctrl.Properties.SetRegion			(STATE[i],	(Region)m_slRegion[STATE[i]]);
				}
			}*/

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

2.921 Beiträge seit 2005
vor 18 Jahren

Wie man sieht habe ich einige Properties mit Namen fest definiert, aber es besteht jederzeit die Möglichkeit feste neue Properties hinzuzufügen. Da diese vom Typ object sind, kann alles hinzugefügt werden.

Eventuell müßtest Du dir für jeden Typ, den Du zurückgeben willst, etwas basteln, damit nicht aus Versehen in eine Funktion die einen int zurückgeben soll, z.B. ein String-Object zurückgibt...

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

roland Themenstarter:in
257 Beiträge seit 2004
vor 18 Jahren

Vielen Dank für deine Hilfe!

Doch benötige ich leider echte Properties, da ich die Properties z. B. mit Controls per DataBinding verknüpfen muss.

Kennt jemand einen Weg über Reflection?

Viele Grüße

roland

4.506 Beiträge seit 2004
vor 18 Jahren

Hallo roland!

Kennt jemand einen Weg über Reflection?

Nach meinem bisherigen Verständnis über Reflection, ist das leider nicht möglich. Du kannst per reflection vorhandene Properties auslesen, aber keine neue hinzufügen.

Aber folgendes würde funktionieren (sehr umständlich):

  • Schritt 1: Du erzeugst eine Klasse dynamisch mit dem Laufzeitkompiler
  • Schritt 2: Du speicherst die IML-kompilierte Version Deiner Klasse in eine DLL
  • Schritt 3: Du lädst diese Klasse über Assembly.Load()
  • Schritt 4: Für das erzeugen neuer Properties schmeißt Du die geladene DLL aus dem GAC und wiederholst Schritt 1-3

Frag mich jetzt aber bitte nicht nach Sourcecode, das ist nämlich schon n bissl komplizierter, als grad mal so online neuer Code erstellt 😉

Ciao
Norman-Timo

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

4.221 Beiträge seit 2005
vor 18 Jahren

Such mal nach ExtenderProvider / IExtenderProvider

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

roland Themenstarter:in
257 Beiträge seit 2004
vor 18 Jahren

Ich werde mich dann mal über die angegeben Quellen informieren.

Danke für eure Antworten!

M
49 Beiträge seit 2005
vor 18 Jahren

Guten Tag.

Eine etwas abgefahrene Möglichkeit ist es den Code dynamisch zur Laufzeit zu generieren und anschließend zu instanzieren. Ein Ausgangspunkt für Informationen ist hier:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpcongeneratingcompilingsourcecodedynamicallyinmultiplelanguages.asp

Die Idee wäre es nun zur Laufzeit eine Klasse zu erstellen, die von der Klasse die erweitert werden soll erbt. Der Code wird dann intern compiliert und anschließend kann man ihn dann via Reflection instanzieren. ASP.NET nutzt diese Funktion recht intensiv.

Meines erachtens nach wäre es dennoch besser mit Collections/Generics bzw. Arrays zu arbeiten. Was Ihnen vorschwebt ist sicherlich sowas wie das Item/Fields Modell aus z.B. Sharepoint, Exchange oder anderen Messaging Anwendungen. Wenn Sie unbedingt Properties brauchen klingt das ein wenig nach Ärger mit DataBinding oder Ärger mit Webservices unter 1.x, die beide Properties brauchen. Aber zumindest für ersteres gibt es im System.ComponentModel Namespace eine ganze Reihe von Interfaces.

-Martin Ehrlich


Martin Ehrlich

roland Themenstarter:in
257 Beiträge seit 2004
vor 18 Jahren

Dieser Artikel klingt interessant, es ist eigentlich so ähnlich wie ich mir das vorgestellt hatte. Allerdinge glaube ich das hier Probleme mit der Performance auftauchen werden. Deshalb habe ich mich dazu entschieden doch lieber ArrayLists und Collections zu verwenden.

308 Beiträge seit 2005
vor 18 Jahren

Hallo roland,

ich glaube nicht. das du Perfomance probleme bekommen würdest.
Da du dem User ja etwas präsentieren willst wirst du ja nicht hundertemale pro Sekunde Objekte dynamisch kreieren wollen.

Ich habe sehr gute Erfahrung damit gemacht. Allerdings gehe ich nicht den Weg über CodeDom sonder direkt über IL und Emit.
Damit spart man sich den Weg über den Kompiler und es wird auch nichts auf der Platte verarbeitet.

Es gibt auch Beispiele wo das dynamische erzeugen von Methoden schneller ist, als eine klassische ausführung (z.B. wenn man eine Rekursion linear abarbeitet)