Reflection sur une liste [Résolu]

Signaler
Messages postés
64
Date d'inscription
lundi 21 avril 2008
Statut
Membre
Dernière intervention
23 octobre 2009
-
Messages postés
6814
Date d'inscription
dimanche 15 décembre 2002
Statut
Modérateur
Dernière intervention
13 octobre 2010
-
Bonjour à tous,

Je reviens vers vous pour une nouvelle question sur la reflexion.

J'ai une class qui possède une List d'objet B, avec B qui hérite de la classe Mère A.

Via la réflexion, je parcours les attributs de ma classe, et lorsque je tombe sur ma liste, j'arrive correctement à vérifier que cette List est de type List (B étant une spécification de A, ca fonctionne).

Mon problème est que je n'arrive pas à exploiter cette liste. En utilisant la méthode getValue() sur le fieldInfo adéquat, j'arrive à récupérer un Objet qui représente cette List. Mon debbugger me confirme que l'objet est bien une liste de B.

Or cependant, je n'arrive pas à effecter un cast ( genre List la = (List) monFieldInfo.getValue(monObjet) ), et je n'arrive pas à parcourir l'objet en question, en tant que liste.

Vous savez comment faire ca ?
C'est assez compliquer d'expliquer, j'espere que cela a été clair ;) Sinon hésitez pas !
A voir également:

9 réponses

Messages postés
64
Date d'inscription
lundi 21 avril 2008
Statut
Membre
Dernière intervention
23 octobre 2009

Salut,

J'ai trouvé une solution qui me convient parfaitement : Au lieu
d'appeler la méthode invokeMember(), je passe par la méthode invoke()
plus générique. De cette manière, je peux reconstituer ma liste d'objet A (class mère) à partir d'une liste d'objet B (classe fille)

Pour les prochains qui auront ce problème, voici ma solution :

        public static List convertToListPersistant(List lb)
        {
            List la = new List();
           
            Type pType = lb.GetType();

            // Récupération du nombre d'entrées
            MethodInfo mCount = pType.GetMethod("get_Count");
            int count = (int) mCount.Invoke(lb, null);

            // On récupére la méthode pour récupérer les objets de la liste
            MethodInfo mi = pType.GetMethod("get_Item");
            for (int i = 0; i < count; i++)
            {
                la.Add( (A) mi.Invoke(lb, new Object[] { i }));
            }

            return la;
        }

Bonne journée à tous!
Messages postés
64
Date d'inscription
lundi 21 avril 2008
Statut
Membre
Dernière intervention
23 octobre 2009

Après avoir bien fouiller sur Internet, je commence à comprendre le problème.

Il n'est pas possible de faire un cast entre mes deux types de List car ce sont des objets différents et que si j'y arrivais, je romprais le fait que la liste soit type-safe !

Pour les explications en détails : http://devlicio.us/blogs/louhaskett/archive/2007/06/13/how-to-cast-between-list-t-s.aspx

La solution serait de parcourir ma liste d'objet B, récupérée par reflection, d'appeller la méthode invokeMember() sur cet objet pour en récupérer chacun des objets. Ces objets seront des objets de Type B, que je pourrais alors caster en objet de Type A pour enfin remplir ma List. Cela vous parait-il cohérent ?

Question subsidiaire : La méthode InvokeMember pour récupérer l'index d'une liste fonctionne comment :s ?
monType.invokeMember( string name,bindingFlags,Binder, Object target, object[] args);

name : Quel est le nom de la méthode ? Pour accéder à une liste je fais List[i] ; Ca doit être quelque chose comme getItem ?
BindingFlags : Correspond au bindingFlags de la méthode appellante ou appellée ?
Binder : Dans les exemple que j'ai trouvé, c'est toujours à null :p
Target : Ca doit être mon objet récupéré par la reflection je suppose ?
Args : Un tableau contenant les index que l'on veut sortir ? genre new object[] {0} pour le premier élément ?

En sachant exactement ces points, je pourrais alors effectuer une boucle sur l'objet contenant ma liste...

Merci d'avance de vos explications.

A+
Messages postés
5487
Date d'inscription
dimanche 4 août 2002
Statut
Modérateur
Dernière intervention
20 juin 2013
54
Bonsoir,
Es-tu certain que la reflexion est indispensable? Car c'est un moyen qui est assez coûteux et généralement pas typé (on travaille beaucoup avec des objects). A utiliser seulement s'il n'y pas d'autres solution dirais-je.
Concernant la question sur InvokeMember, voir
http://msdn.microsoft.com/fr-fr/library/66btctbe(VS.80).aspx

<hr />
-My Blog-
Messages postés
64
Date d'inscription
lundi 21 avril 2008
Statut
Membre
Dernière intervention
23 octobre 2009

Hello,

Oui je suis bien sur de la reflexion :)

Par contre, c'est la merde : Le compact framework ne supporte pas cette propriété !
Je vais retomber sur un problème que j'ai déjà évoqué sur ce forum, à savoir, réaliser un cast spécifique à partir de la réflexion. C'est à dire, dans l'exemple énoncé :

Caster l'objet récupéré par la méthode getValue() qui représente une List (Mais qui est un objet!) en une List, et de la parcourir...

Précédent thread sur ce sujet : http://www.csharpfr.com/infomsg_REFLECTION-INSTANCES-ATTRIBUTS_1127284.aspx

Aie Aie Aie,
j'ai vraiment besoin d'aide
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
93
Salut,

Je risque d'être à côté de la plaque car je ne crois pas vraiment avoir saisi le fond du problème, mais si le but est de parcourir les items de la liste en les utilisant en tant qu'instance de A, il n'y a aucun intérêt à sortir l'artillerie lourde :

IList liste = laListe as IList;


foreach (A currentA in liste)
{
  // ...
}

/*
coq
MVP Visual C#
CoqBlog
*/
Messages postés
5487
Date d'inscription
dimanche 4 août 2002
Statut
Modérateur
Dernière intervention
20 juin 2013
54
Pourquoi pas:
List<
A> a = b.ConvertAll(
new
Converter<
B,
A>(
delegate(
B b) {
return (
A)b; }));

??

<hr />
-My Blog-
Messages postés
64
Date d'inscription
lundi 21 avril 2008
Statut
Membre
Dernière intervention
23 octobre 2009

Parce que b n'est pas connu.

Cela pourrait être c ou d avec b, c et d, des classes filles de a.
Et dans ce cas là, il faudrait que je fasse un test pour chaque objet fille.

Si c'est un b... je fais :

    List<
A> a = b.ConvertAll(
newConverter<
B,
A>(
delegate(
B b) {
return (
A)b; }));

Si c'est un c... je fais :

  List<
A> a = c.ConvertAll(
newConverter<
C,
A>(
delegate(C
c) {
return (
A)c; }));
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
93
Du coup je persiste sur l'utilisation d'IList :p

/*
coq
MVP Visual C#
CoqBlog
*/
Messages postés
6814
Date d'inscription
dimanche 15 décembre 2002
Statut
Modérateur
Dernière intervention
13 octobre 2010
28
Bonjour,

D'après ton bout de code tu cherches juste à convertir une List en ListCyril - MSP - MCPD ASP.net & MCTS SQL - Consultant indépendant