2010-08-05 11 views
30

Non riesco a capire come fare questo lavoro:Come si crea un array C# usando Reflection e solo le informazioni sul tipo?

object x = new Int32[7]; 
Type t = x.GetType(); 

// now forget about x, and just use t from here. 

// attempt1 
object y1 = Activator.CreateInstance(t); // fails with exception 

// attempt2 
object y2 = Array.CreateInstance(t, 7); // creates an array of type Int32[][] ! wrong 

Qual è la salsa segreta? Posso far funzionare il secondo se riesco a ottenere il tipo di elementi dell'array, ma non l'ho nemmeno immaginato.

+3

Mi hai avuto a "salsa segreta". =) –

risposta

30

Solo per aggiungere alla risposta di Jon. La ragione per cui il tentativo 1 non riesce è perché non esiste un costruttore predefinito per Int32[]. Devi fornire una lunghezza. Se si utilizza il sovraccarico, che utilizza una serie di argomenti, funzionerà:

// attempt1 
object y1 = Activator.CreateInstance(t, new object[] { 1 }); // Length 1 
+3

Entrambe queste risposte mi tirano fuori dal sottaceto, ma penso che questo sia il metodo più elegante. Non avrei indovinato questa risposta, ma vedo come è necessario fornire un argomento al costruttore di un array, perché la lunghezza dell'array non fa parte del tipo. –

+0

Ho appena usato questo e il blocco da http://stackoverflow.com/a/20052747/561690 per abilitare un'implementazione di Deep Copy che gestisca gli array - probabilmente non è il modo migliore per farlo, ma funziona per me! Grazie! –

+0

Più semplice: Activator.CreateInstance (t, 1) –

41

È necessario Type.GetElementType() per ottenere il tipo non-array:

object x = new Int32[7]; 
Type t = x.GetType(); 
object y = Array.CreateInstance(t.GetElementType(), 7); 

In alternativa, se è possibile ottenere il tipo di elemento direttamente, utilizzare tale:

Type t = typeof(int); 
object y = Array.CreateInstance(t, 7); 

In sostanza, Array.CreateInstance bisogno della tipo di elemento dell'array da creare, non il tipo di array finale.

+0

Questo non risponde perché non funziona con // attempt1 anche se, che sono piuttosto curioso di me stesso (dato che // tentativo2 funziona). – zebediah49

+0

Alcuni secondi dopo che ho postato la mia domanda, ho scoperto GetElementType(), ed è così che l'ho implementato. Il mio obiettivo era creare un widget derivato TreeView che ti consentisse di gettare qualsiasi struttura (con campi arbitrari, inclusi array, primati e altre strutture) e visualizzare l'intero oggetto e permettendoti di modificarlo e darti una copia del struttura modificata –

Problemi correlati