[C#] Accedere a una collezione attraverso la riflessione


Answers

Ho provato ad usare una tecnica simile a quella suggerita da Darren, ma attenti solo che non solo le collezioni implementano IEnumerable. string per esempio è anche IEnumerable e itererà sopra i caratteri.

Ecco una piccola funzione che sto usando per determinare se un oggetto è una collezione (che sarà enumerabile anche perché ICollection è anche IEnumerable).

    public bool isCollection(object o)
    {
        return typeof(ICollection).IsAssignableFrom(o.GetType())
            || typeof(ICollection<>).IsAssignableFrom(o.GetType());
    }
Question

C'è un modo per iterare (attraverso foreach preferibilmente) su una collezione utilizzando la riflessione? Sto iterando sulle proprietà di un oggetto usando il reflection, e quando il programma arriva a un tipo che è una collection, mi piacerebbe che iterasse sul contenuto della collezione e sia in grado di accedere agli oggetti nella collezione.

Al momento ho un attributo impostato su tutte le mie proprietà, con un flag IsCollection impostato su true sulle proprietà che sono raccolte. Il mio codice controlla questo flag e se è vero, ottiene il Type usando reflection. Esiste un modo per richiamare GetEnumerator o Items in qualche modo su una raccolta per poter iterare sugli articoli?




Quando usi la riflessione non stai necessariamente usando un'istanza di quell'oggetto. Dovresti creare un'istanza di quel tipo in grado di scorrere le proprietà dell'oggetto. Quindi se stai usando reflection usa il metodo ConstructorInfo.Invoke () (?) Per creare una nuova istanza o puntare a un'istanza del tipo.




Se non stai utilizzando un'istanza dell'oggetto ma piuttosto un tipo, puoi utilizzare quanto segue:

// type is IEnumerable
if (type.GetInterface("IEnumerable") != null)
{
}



Il meglio che potresti fare sarebbe controllare se l'oggetto implementa determinate interfacce di raccolta - probabilmente IEnumerable sarebbe tutto ciò di cui hai bisogno. Quindi si tratta semplicemente di chiamare GetEnumerator () dall'oggetto e di utilizzare IEnumerator.MoveNext () e IEnumerator.Current per accedere alla raccolta.

Questo non ti aiuterà se la collezione non implementa quelle interfacce, ma se questo è il caso non è molto di una collezione, suppongo.




Links