2009-03-10 7 views
1

J'ai un objet que j'ai fini avec via un appel de réflexion:objet [] de ReadOnlyCollection <T>

object readOnlyCollectionObject = propertyInfo.GetValue(someEntity, null);

Je sais que cet objet est un ReadOnlyCollection générique. Il pourrait s'agir d'un ReadOnlyCollection<Cat>, ReadOnlyCollection<Dog>, etc. Pour l'amour de l'argument, disons simplement qu'il s'agit d'un ReadOnlyCollection<T>.

Même si un Dog dérive d'un objet, je sais qu'un ReadOnlyCollection<Dog> ne dérive pas d'un ReadOnlyCollection<object>. Donc même si j'utilise la réflexion pour appeler la méthode CopyTo, j'ai encore besoin de connaître le type spécifique de ReadOnlyCollection, ce que je veux éviter.

Je veux savoir comment extraire tous les éléments de ReadOnlyCollection sous la forme d'un tableau de références d'objet sans avoir à connaître le type spécifique (T) du ReadOnlyCollection<T>.

Répondre

3

Beaucoup d'autres réponses mentionnent Cast() et ToArray, toutes celles-ci ont un problème avec le type. Comme vous le dites, vous ne saurez pas quel IEnumerable spécialisé votre propriété implémentera. Cependant, vous pouvez être sûr qu'ils vont tous implémenter l'interface ICollection non générique.

ICollection readOnlyCollectionObject = (ICollection)propertyInfo.GetValue(someEntity, null); 
object[] objs = new ArrayList(readOnlyCollectionObject).ToArray(); 

ou

ICollection readOnlyCollectionObject = (ICollection)propertyInfo.GetValue(someEntity, null); 
object[] objs = new object[readOnlyCollectionObject.Count]; 
for (int i = 0; i < readOnlyCollectionObject.Count; i++) 
    objs[i] = readOnlyCollectionObject[i]; 

Edit: Vous avez oublié de mettre à jour le casting de IEnumerable à ICollection

+0

Problème est la première ligne ne compilera pas parce que vous ne pouvez pas convertir de IEnumerable à ICollection. – hkdk3107

+0

Modifié. Doit avoir été une faute de frappe difficile à repérer. – erikkallen

+0

Cette solution est très soignée car elle ne se soucie pas du tout des génériques. – hkdk3107

3

Eh bien, vous pouvez utiliser la méthode d'extension Cast sur la readonly collection et puis le convertir en un tableau d'objets, mais, compte tenu du fait que c tableaux # sont covariant, vous pouvez simplement faire:

object[] objs = myReadOnlyCollection.ToArray(); 

Comme Pop Catalin mentionné (modifier) ​​

, les seules œuvres si T est un type de référence. Utilisez la méthode Cast autrement.

(Edit2)

Votre mise à jour à la question change les choses un peu ... Je pense que ce que vous essayez de faire est impossible. Vous voulez convertir en un type explicite à l'heure de compilation qui est uniquement disponible à runtime. Dans ce cas, la seule façon d'accéder à la collection est de réfléchir.

+0

Les tableaux de types de référence sont covariants, cela ne fonctionnera que si T est un type de référence. –

+0

Veuillez jeter un autre coup d'oeil. J'ai mis à jour la description pour montrer comment j'ai obtenu cet objet. – hkdk3107

+0

humm. Cela change un peu les choses. Voir ma deuxième mise à jour. –

1
var myArray = readOnlyCollection.Cast<object>().ToArray(); 
-1

Voulez-vous un clone en profondeur de la collection? Si vous voulez clone profond essayer ce code ci-dessous pour le clonage profond de mémoire:

// deep copy in separeate memory space 
public object Clone() 
{ 
    MemoryStream ms = new MemoryStream(); 
    BinaryFormatter bf = new BinaryFormatter(); 
    bf.Serialize(ms, this); 
    ms.Position = 0; 
    object obj = bf.Deserialize(ms); 
    ms.Close(); 
    return obj; 
} 
0

Cast votre collection à une liste d'objets, puis appelez ToArray():

ReadOnlyCollection<string> s; 
object[] o = s.Cast<object>().ToArray(); 

Fonctionne uniquement en C# 3.5 parce que des méthodes d'extension.

Questions connexes