Laden...

InvokeMember und Arrays

Erstellt von GhoBu vor 19 Jahren Letzter Beitrag vor 19 Jahren 2.189 Views
G
GhoBu Themenstarter:in
36 Beiträge seit 2004
vor 19 Jahren
InvokeMember und Arrays

Moin!

Wenn ich mit mittels CreateInstance z.B. eine ArrayList erzeuge, wie kann ich dann per InvokeMember ein Objekt hinzufügen?

Zu einem geht es ja hervorragend über die Methode "Add". Ich möchte aber per InvokeMember auf die Property "Item" zugreifen... Dann klappts auch mit normalen Arrays und nicht nur mit ArrayLists. 😉
Aber ein Aufruf von


object o=System.Activator.CreateInstance(Type.GetType("ArrayList"));
o.GetType().InvokeMember("Item",BindingFlags.Default|BindingFlags.SetProperty,null,o,new object[] {0,"XYZ"});

führt zu einer System.ArgumentOutOfRangeException.

Nun liegt es sicher daran, dass das interne Array noch keinen Speicher für irgendwelche Objekte reserviert hat...

Mir fällt bis jetzt nur die Möglichkeit ein, mit der Methode "Add" aus IList zu arbeiten... Und bei normalen Arrays müsste man ein neues Array mit einer Speicherstelle mehr erzeugen, den ganzen Krempel umkopieren und das neue Element hinzufügen....

Wie bekomme ich das geschickter hin? So dass es mit Arrays und ArrayLists funktioniert. Immerhin haben doch alle die Property "Item". ?(

Gruß
Jürgen

C
980 Beiträge seit 2003
vor 19 Jahren

Schon versucht dem ArrayList Konstruktor eine initialcount zu übergeben?

G
GhoBu Themenstarter:in
36 Beiträge seit 2004
vor 19 Jahren

Nein, habe ich noch nicht versucht... Das würde aber wiederum bedeuten, dass ich vorher wissen muss, wieviele Elemente das Array hat.

Und wenn ich es wüsste, wie übergebe ich denn eine initiale Grösse? Bei einer ArrayList kann ich diese ja dem Konstruktor übergeben... aber bei einem Array?

C
980 Beiträge seit 2003
vor 19 Jahren

Falls du das Array mit Array.CreateInstance dynamisch generierst kannst neben dem Typ auch gleich die Dimension(en) angeben - die Array Klasse hat auch einen Indexer der GetValue/SetValue wrappt, ist aber wenn ich das richtig sehe private.

Ansonsten (Ich nehme an mit "Item" meinst du den Indexer): Die Methoden die du in Reflection für Indexer siehst heissen "set_Item" und "get_Item".

G
GhoBu Themenstarter:in
36 Beiträge seit 2004
vor 19 Jahren

Ich habe mal einige Versuche gestartet:

Erzeugung einer ArrayList mit einer initialen Kapazität von 100 (ist aber egal, da die initiale Kapazität 16 beträgt) mit Activator.CreateInstance

Hinzufügen eines Objekts an die Stelle 0 mittels InvokeMember("Item",.....):
System.ArgumentOutOfRangeException
in System.Collections.ArrayList: set_Item(int,object)

Hinzufügen eines Objekts an die Stelle 1 mittels InvokeMember("Item",.....):
System.ArgumentOutOfRangeException
in System.Collections.ArrayList: set_Item(int,object)

Hinzufügen eines Objekts an die Stelle 0 mittels InvokeMember("set_Item",.....):
System.MissingFieldException
in System.MonoType: InvokeMember(string,.......)

Erzeugung eines ObjectArrays mit einer initialen Grösse von 100 mit Array.CreateInstance

Hinzufügen eines Objekts an die Stelle 0 mittels InvokeMember("Item",......):
System.MissingFieldException
in System.MonoType: InvokeMember(string,.......)

Hinzufügen eines Objekts an die Stelle 0 mittels InvokeMember("set_Item",......):
System.MissingFieldException
in System.MonoType: InvokeMember(string,.......)

Hinzufügen eines Objekts an die Stelle 0 mittels InvokeMember("SetValue",......):
System.MissingFieldException
in System.MonoType: InvokeMember(string,.......)

Den größten Erfolg hatte ich noch in der ArrayList. Scheinbar ruft Item die Methode set_Item auf, die ich aber nicht direkt aufrufen kann. Eine ArrayList kann ich ja nur mit einer initialen Kapazität erzeugen. Das ist aber leider nicht das gleiche wie die Gössenangabe eines Arrays...

*grübel*

C
980 Beiträge seit 2003
vor 19 Jahren

Wäre es nicht trotzdem einfacher Arrays und ArrayLists getrennt zu behandeln? Dürfte auch wesentlich performanter werden als die Reflection-Spielchen ...

btw: Arrays und ArrayLists implementieren alle das IList Interface (da kommt auch die Item Property her) ... durch ein Casten nach IList könntest du damit jegliche Reflection sparen ...

G
GhoBu Themenstarter:in
36 Beiträge seit 2004
vor 19 Jahren

Ist wahrscheinlich wirklich besser, unterschiedliche Verfahren für ArrayLists und Arrays zu wählen.

Was mich nur wundert: Warum kann ich nach dem Casten auf die Property Item zugreifen, aber nicht mit InvokeMember??? Naja...

Ich werden nun prüfen mit Type.IsArray und dann entweder nach dem Casten die Methode Add bzw. das Property Item benutzen. Ausserdem muss ich mich darum kümmern, dass die Anzahl der einzufügenden Elemente bei den Arrays vorher bekannt ist.

Vielen Dank für Deine Antworten!