2012-11-07 1 views
0

J'ai un tableau d'objets (object[]). Tous les éléments de ce tableau ont le même type (inconnu à la compilation). J'ai besoin de convertir ce tableau dans un tableau typé, c'est-à-dire, si les éléments sont des entiers, je veux obtenir un int[].Unboxing automatique

J'ai examiné la méthode Array.ConvertAll, mais j'ai besoin de spécifier un type spécifique dans le modèle, ce qui signifie que je dois obtenir le type d'élément, puis appeler ConvertAll pour chaque cas possible.

J'ai également examiné le mot-clé dynamic sans plus de chance (ressemble à dynamic[] est le même que object[]).

Comment puis-je y parvenir?

+1

Pourquoi faire tu veux faire ça? Comment allez-vous utiliser le tableau résultant? Est-ce que cela doit vraiment être un type d'exécution (objet 'Type'), ou est-ce que les génériques (paramètre de type' T') sont également acceptables? – svick

+0

Juste intéressant - après la conversion d'exécution 'object []' à int [] ', que ferez-vous lors de l'exécution de votre collection? Au moment de la compilation, vous ne pourrez pas utiliser vos objets comme 'int's –

+0

J'utilise une bibliothèque avec une méthode comme' theMethod (object array) 'où array doit être un tableau d'un type donné (une erreur est retournée dans le cas de 'object []'). – gregseth

Répondre

2

similaire à la solution de Jon vous pouvez faire sans dynamique et utiliser le type Array:

public Array Convert(Array a) { 
    if (a.GetLength(0) == 0){ 
    return new int[0]; 
    } 
    var type = a.GetValue(0).GetType(); 
    var result = Array.CreateInstance(type, a.GetLength(0)); 
    for (int i = 0; i < a.GetLength(0); i++) { 
    result.SetValue(a.GetValue(i), i); 
    } 
    return result; 
} 
+2

Nice - c'est une meilleure solution que la mienne, bien que j'utilise probablement 'object []' comme entrée, donc vous pouvez juste utiliser '0' et' a.Length' au lieu de toutes les limites inférieures/supérieures. –

+0

@JonSkeet Merci - Je n'étais pas au courant qu'aujourd'hui, vous ne pouvez pas créer de tableaux avec des limites inférieures autres que 0 - ils ont évidemment changé cela dans VB 2003. Je vais mettre à jour l'extrait. – Sebastian

4

On dirait que vous voulez quelque chose comme:

dynamic array = Array.CreateInstance(input[0].GetType(), input.Length); 
for (int i = 0; i < input.Length; i++) 
{ 
    array[i] = (dynamic) input[i]; 
} 

Voici les poignées dynamic juste la partie de conversion pour vous.

Autre possibilité:

public static Array ConvertArray(object[] input) 
{ 
    dynamic sample = input[0]; // Just used for type inference 
    return ConvertArrayImpl(sample, input); 
} 

private static T[] ConvertArrayImpl<T>(T sample, object[] input) 
{ 
    return input.Cast<T>().ToArray(); 
} 

Vous pourriez faire passer l'appel ConvertArrayImpl avec la réflexion manuelle bien sûr, au lieu d'utiliser le typage dynamique.

Notez également que tous ces échouera si le tableau d'entrée est vide ...

+0

Votre première version ne fonctionne pas, elle lève 'RuntimeBinderException' avec le message" Impossible de convertir implicitement le type 'objet' en 'int'. ". Changer le corps de la boucle en 'array [i] = entrée (dynamique) [i];' répare cela. – svick

+0

@svick: Bonne prise - fixe, merci. –

Questions connexes