2010-08-05 3 views
30

Je ne peux pas comprendre comment faire ce travail:Comment créer un tableau C# à l'aide de Reflection et uniquement des informations de type?

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 

Quelle est la sauce secrète? Je peux faire fonctionner le second si je peux obtenir le type des éléments du tableau, mais je ne l'ai pas compris non plus.

+3

Vous m'aviez à "secret sauce". =) –

Répondre

30

Juste pour ajouter à la réponse de Jon. La raison pour laquelle la tentative 1 échoue est qu'il n'existe aucun constructeur par défaut pour Int32[]. Vous devez fournir une longueur. Si vous utilisez la surcharge, qui prend un tableau d'arguments, cela fonctionnera:

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

Ces deux réponses me sortent du pétrin, mais je pense que c'est la méthode la plus élégante. Je n'aurais pas deviné cette réponse, mais je vois comment il est nécessaire de fournir un argument au constructeur d'un tableau, car la longueur du tableau ne fait pas partie du type. –

+0

Juste utilisé ceci et le morceau de http://stackoverflow.com/a/20052747/561690 pour activer une implémentation Deep Copy qui gère les tableaux - probablement pas la meilleure façon de le faire, mais ça marche pour moi! Merci! –

+0

Plus simple: Activator.CreateInstance (t, 1) –

41

Vous devez Type.GetElementType() pour obtenir le type non-tableau:

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

Alternativement, si vous pouvez obtenir le type de l'élément directement, utilisez que:

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

Fondamentalement, Array.CreateInstance a besoin de la type d'élément du tableau à créer, pas le type de tableau final.

+0

Cela ne répond pas pourquoi ça ne marche pas avec // try1, ce qui me rend plutôt curieux (vu que // essay2 fonctionne). – zebediah49

+0

Quelques secondes après avoir posté ma question, j'ai découvert GetElementType(), et c'est ainsi que je l'ai implémenté. Mon objectif était de créer un widget dérivé de TreeView qui vous permet de lancer n'importe quelle structure (avec des champs arbitraires, y compris des tableaux, des primitives et d'autres structures), afficher le tout et vous permettre de le modifier. structure éditée. –

Questions connexes