Reflection sur une liste

Résolu
t00f Messages postés 64 Date d'inscription lundi 21 avril 2008 Statut Membre Dernière intervention 23 octobre 2009 - 20 mai 2008 à 19:40
jesusonline Messages postés 6814 Date d'inscription dimanche 15 décembre 2002 Statut Membre Dernière intervention 13 octobre 2010 - 31 mai 2008 à 13:23
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 !

9 réponses

t00f Messages postés 64 Date d'inscription lundi 21 avril 2008 Statut Membre Dernière intervention 23 octobre 2009
27 mai 2008 à 11:30
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!
3
t00f Messages postés 64 Date d'inscription lundi 21 avril 2008 Statut Membre Dernière intervention 23 octobre 2009
20 mai 2008 à 21:42
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+
0
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
20 mai 2008 à 22:31
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-
0
t00f Messages postés 64 Date d'inscription lundi 21 avril 2008 Statut Membre Dernière intervention 23 octobre 2009
21 mai 2008 à 09:14
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
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_coq Messages postés 6349 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 101
24 mai 2008 à 12:47
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
*/
0
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
27 mai 2008 à 17:45
Pourquoi pas:
List<
A> a = b.ConvertAll(
new
Converter<
B,
A>(
delegate(
B b) {
return (
A)b; }));

??

<hr />
-My Blog-
0
t00f Messages postés 64 Date d'inscription lundi 21 avril 2008 Statut Membre Dernière intervention 23 octobre 2009
29 mai 2008 à 11:10
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; }));
0
cs_coq Messages postés 6349 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 101
31 mai 2008 à 12:08
Du coup je persiste sur l'utilisation d'IList :p

/*
coq
MVP Visual C#
CoqBlog
*/
0
jesusonline Messages postés 6814 Date d'inscription dimanche 15 décembre 2002 Statut Membre Dernière intervention 13 octobre 2010 29
31 mai 2008 à 13:23
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
0
Rejoignez-nous