Jag har nu letat i runt 9 timmar och fortfarande inte hittat någonting av värde för att lösa mitt problem. Jag har en klass skriven i C#, denna klass vill jag ska kunna skapa dynamiska properties "i" sig själv. Dvs, i konstruktorn skickar jag med lite data, den kan se ut såhär: Du kan använda dig av System.Reflection.Emit namespacet. Sök på System.Reflection.Emit i SDK dokumentationen så hittar du massor av exempel på hur du skapar objekt dynamiskt. Tack för svaret. Jo, alternativet är ju att göra precis som du säger, med en Hashtable, och det lutar mer och mer åt att det får bli så. Tack för ditt svar! Har kollat lite hastigt på System.Reflection.Emit nu och det är möjligt att jag inte insett alla möjligeheter, men tillåter inte Emit bara att skapa "nya" objekt osv, kan man inte "lägga till" funktionalitet i befintliga klasser? Problemet är väl att du ju hela tiden måste veta vilka properties som finns. Jag är inte så instatt i Emit. Jag vet att Wrox Press skulle eller har skrivit en artikel om hur man med hjälp av Emit kan gå in och lägga till och förändra en applikation. Av säkerhets skäl så tror jag inte att det ska fungera, för om det går att förändra en klass members så har hackers möjligheter till att förändra befintlig kod, så jag är är väldigt tveksam till att det går att lägga till members i ett befintligt objekt. Problemet är väl att du ju hela tiden måste veta vilka properties som finns. Jo, det låter ju logiskt :) Jag håller med Johan, problemet med dynamiskt skapadande av klasser är du måste med hjälp av reflection skapa instanser och hämta/sätta egenskaper. I dessa fall så måste du ange namnet på dina egenskaper i text. Du kan iofs med Emit skapa upp en assembly på disk som du sedan refererar till, men då tappar du poängen med att dynamiskt skapa egenskaper utifrån en XML-fil. Så Johans förslag med GetProperty är bra och går mkt fortare att implementera. Som slutsats och "lösning" får bli att det är snabbare/enklare/smidigare att låta min klass ta in XML-datat, spara ner det i en Hashtable, och sen ha en default property som tar emot ett namn och returnerar det som finns i min Hashtable under det namnet.Dynamiska egenskaper i en klass
<code>
<User>
<Firstname>Christoffer</Firstname>
<Lastname>Persson</Lastname>
</User>
</code>
...då vill jag att klassen ska skapa egenskaperna Firstname och Lastname.
Så att jag utifrån direkt kan komma åt dem via:
<code>
DynProp dynProp = new DynProp(xmlSource);
textFirstname.Text = dynProp.Firstname; // returnerar 'Christoffer'
textLastname.Text = dynProp.Lastname; // returnerar 'Persson'
</code>
Jag har ingen aning om hur detta ska lösas. Alternativet är väl att lägga en collection eller något sånt som default-property, men det hade varit så underbart att få rätt på detta på ovanstående sätt.
Tacksam för hjälp!Sv: Dynamiska egenskaper i en klass
/Fredrik Normén NSQUARED2
http://www.nsquared2.netSv: Dynamiska egenskaper i en klass
<code>
DynProp dynProp = new DynProp(xmlSource);
textFirstname.Text = dynProp.Firstname; // returnerar 'Christoffer'
textLastname.Text = dynProp.Lastname; // returnerar 'Persson'
</code>
Problemet är väl bara att hur vet du att din DynProp innehåller Firstname och LastName? Och hur vet kompilatorn det?
Ett annat sätt hade ju t.ex. varit att ha nån typ av nyckel, värde och sen kunna hämta ut via en metod t.ex. GetProperty(string key)
De dynamiska propertiesarna kan du ju lagra t.ex. i en hashtable.
Lite idéer bara...Sv: Dynamiska egenskaper i en klass
Koden som skickar in XML-datat vet vilken data som finns, så den vet även vilka egenskaper som ska finnas.
I PHP5 finns det två fördefinierade namn, "__get(name)" och "__set(name, value)". Det är precis den funktionaliteten jag vill åt. Men som du också säger, kompilatorn klagar ju när egenskapen jag vill åt inte finns från början.Sv: Dynamiska egenskaper i en klass
Sv: Dynamiska egenskaper i en klass
Jag menar visst du kan säkert skapa en dynamisk klass, instansiera den men sen?
ok, du kan ju skapa en instans med Activator.CreateInstance("klassnamn");
men för att plocka ut en Property måste du ju ändå använda nåt sätt där du kan hämta ut värdet av propertyn via ett strängnamn eller liknande och då faller lite av meningen med att göra det eftersom det borde vara lättare att implementera en egen variant av GetProperty(string name);Sv: Dynamiska egenskaper i en klass
Du skulle kunna lösa det genom att du först skapar en basklass som innehåller grundfunktionalitet och sedan med Emit dynamiskt skapar upp subklasser som ärver basklassen. När du skapar subklassen med Emit så skapar du även egenskaper utifrån ditt XML dokument.
/Fredrik Normén NSQUARED2
http://www.nsquared2.netSv: Dynamiska egenskaper i en klass
Jag menar visst du kan säkert skapa en dynamisk klass, instansiera den men sen?
ok, du kan ju skapa en instans med Activator.CreateInstance("klassnamn");
men för att plocka ut en Property måste du ju ändå använda nåt sätt där du kan hämta ut värdet av propertyn via ett strängnamn eller liknande och då faller lite av meningen med att göra det eftersom det borde vara lättare att implementera en egen variant av GetProperty(string name);
Min tanke var att det hela skulle fungera såhär:
1. Kod hämtar XML-data, den VET vilken data som finns.
2. Skapar en instans av DynProp-klassen, skickar med XML-datat till konstruktorn.
3. DynProp läser igenom XML-datat och lagrar informationen i en Hashtable, och skapar samtidigt nya, dynamiska, egenskaper i sig själv.
4. Den ursprungliga koden kan se komma åt den information som den vet finns, via egenskaper.
Visst, allting talar för att det är bättre att lägga en Default-metod som tar in ett namn och returnerar värdet, informationen finns ju redan i en hashtable. Då blir det istället för DynProp.Firstname alltså DynProp["Firstname"]. Men det hade varit så stiligt om jag fått till det med egenskaperna istället.
Men, jag för nog ge upp min idé och se till prestanda och logik istället... :)Sv: Dynamiska egenskaper i en klass
Men om jag då skapar en dynamisk klass som ärver från min basklass, med de egenskaper som finns i XML-datat. Hur använder jag sen den klassen? Måste den inte typ kompileras? Och kan man verkligen komma åt egenskaperna med Class.Property, måste man inte använda sig av Class.GetProperyValue(name), eller något liknande?
Som Johan sa här innan, även om när den dynamiska klasses skapas och då får nya egenskaper, så vet ju inte kompilatorn om det och kan därför inte godkänna koden?
Trodde faktikst att det skulle finnas en enklare lösning till detta, typ en catch-all-egenskap som tar in namn och värde på set, och ett namn på get. Sen är det upp till den att spara/hämta informationen till varje property.Sv: Dynamiska egenskaper i en klass
/Fredrik Normén NSQUARED2
http://www.nsquared2.netSlutsats och lösning
Här ett fungerande exempel med SqlDataReader som data-källa:
<code>
public class DataDetails
{
private Hashtable _fields = new Hashtable();
public object this[string name]
{
get
{
if (_fields.Contains(name))
{
return _fields[name];
}
else
{
return null;
}
}
}
public DataDetails(SqlDataReader reader)
{
for (int i = 0; i < reader.FieldCount; i++)
{
_fields.Add(reader.GetName(i), reader[i]);
}
}
}
</code>