IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Problème de reflexion : récursivité possible ?


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite Avatar de kheironn
    Homme Profil pro
    Chef de projets technique C# / MVC / .Net
    Inscrit en
    Février 2007
    Messages
    822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projets technique C# / MVC / .Net
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2007
    Messages : 822
    Par défaut Problème de reflexion : récursivité possible ?
    Bonjour,
    j'ai codé une classe générique qui me permet de faire des conversions du contenu de toute les propriétés de type string d'une classe de type T.
    Mais voilà, ma classe T peut contenir des types non primitifs et je souhaites rentrer dans ces types et appliquer la conversion. Bref faire de la récursivité si possible.

    voici ma classe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
        public class FieldConvertor<T> where T : new()
        {
            public T Item { get; set; }
     
            public FieldConvertor(object item)
            {
                Item = (T)item;
            }
     
            public T ConvertStringPropertiesToHtmlTag()
            {
                PropertyInfo[] properties = typeof(T).GetProperties();
                foreach (PropertyInfo property in properties)
                    if (property.PropertyType.Name == typeof(string).Name)
                    {
                        object propertyValue = property.GetValue(this.Item, null);
                        if (propertyValue != null && property.GetSetMethod() != null)
                            property.SetValue(this.Item, propertyValue.ToString().Replace("[[", "<").Replace("]]", ">"), null);
                    }
                return this.Item;
            }
     
            public T ConvertStringPropertiesFromHtmlTag()
            {
                PropertyInfo[] properties = typeof(T).GetProperties();
                foreach (PropertyInfo property in properties)
                    if (property.PropertyType.Name == typeof(string).Name)
                    {
                        object propertyValue = property.GetValue(this.Item, null);
                        if (propertyValue != null && property.GetSetMethod() != null)
                            property.SetValue(this.Item, propertyValue.ToString().Replace("<", "[[").Replace(">", "]]"), null);
                    }
                return this.Item;
            }
        }
    Mon problème est comment récupérer le type T2 dans une List<T2>, par exemple, afin de faire de la récursivité ?

    Au passage, si vous avez une remarque pour améliorer, n'hésitez-pas.

    Voici un exemple d'utilisation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
            public ViewResult Details(int id)
            {
                Character character = db.Characters.Find(id);
                character = new FieldConvertor<Character>(character).ConvertStringPropertiesToHtmlTag();
                return View(character);
            }

  2. #2
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 197
    Par défaut
    pas trop regardé le code mais pour faire ca il ne faut pas de generics je pense mais juste un parametre Object

    sur la classe Objet il y a .GetType qui permet de connaitre le type et de faire de la reflection, la récursivité est alors possible
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Membre émérite Avatar de kheironn
    Homme Profil pro
    Chef de projets technique C# / MVC / .Net
    Inscrit en
    Février 2007
    Messages
    822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projets technique C# / MVC / .Net
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2007
    Messages : 822
    Par défaut
    Merci de ta réponse, je vais essayer de dégager les generics.

  4. #4
    Membre émérite
    Avatar de neilbgr
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Août 2004
    Messages
    651
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 651
    Par défaut
    Mais pourquoi jeter les génériques ? surtout que le conseil est donné par une personne qui a l'honnêteté de dire qu'il n'a même pas lu le code !?

    En gardant les génériques, il te suffit de faire la "reflection" sur le type, et il y a (évidement) tout ce qu'il faut pour traiter les types génériques.
    Voir notamment la méthode GetGenericArguments et les autres membres de la classe Type.

  5. #5
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 197
    Par défaut
    on peut planter des clous avec une masse mais le marteau reste quand même plus adapté

    les generics c'est bien, mais je ne vois pas ce que ca apporte ici, et donc si ca ne sert à rien autant s'en passer
    l'utilité des generics c'est de pouvoir retourner des valeurs typées, ici je ne vois pas l'interet de retourner l'instance

    le code je l'avais lu, c'est juste que quand je prends pas le temps de passer par un convertisseur c#/vb.net je préfère pondérer ma réponse ; là je l'ai converti
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  6. #6
    Membre émérite Avatar de kheironn
    Homme Profil pro
    Chef de projets technique C# / MVC / .Net
    Inscrit en
    Février 2007
    Messages
    822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projets technique C# / MVC / .Net
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2007
    Messages : 822
    Par défaut
    Bonjour,
    J'utilise ensuite l'instance retournée dans mon return view(instance).
    C'est ce qui m'a fait pencher pour l'utilisation de génériques.

    @neilbgr : j'ai vu ces méthodes, mais je n'ai pas dû m'en servir correctement, car je n'obtenais pas le résultat attendu.

    Mon but est d'identifier les List<T> dans une instance afin d'y entrer et de faire les mêmes modifs que dans mon instance principale.
    Identifier que c'est une List, facile, mais le Type T là ??? Je me suis basé sur le FullName de PropertyType et ça marche.

    Ensuite je suis confronté au fait que je ne peux pas utiliser un Foreach pour modifier directement les instances de l'itération. Donc je voulais créer une List<T> où T serait le type que j'ai identifié. Mais là nouveau blocage !
    impossible de faire List<TypeOf(...)> ou List<MonType.GetType()>...
    une idée ?

    Pour le moment, j'ai fait des méthodes que j'appelle explicitement dans mon contrôleur, mais il serait préférable de tout faire en un seul appel de méthode.

  7. #7
    Membre émérite Avatar de kheironn
    Homme Profil pro
    Chef de projets technique C# / MVC / .Net
    Inscrit en
    Février 2007
    Messages
    822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projets technique C# / MVC / .Net
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2007
    Messages : 822
    Par défaut
    finallement, j'ai adopté cette sollution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
        public class FieldConvertor
        {
            public enum ConvertMode { HtmlToWiki, WikiToHtml }
     
            private static string GetTransformations(string stringToTransform, ConvertMode mode)
            {
                switch (mode)
                {
                    case ConvertMode.HtmlToWiki:
                        stringToTransform = stringToTransform.Replace("<", "[[").Replace(">", "]]");
                        break;
                    case ConvertMode.WikiToHtml:
                        stringToTransform = stringToTransform.Replace("[[", "<").Replace("]]", ">");
                        break;
                    default:
                        break;
                }
                return stringToTransform;
            }
     
            public static void ConvertStringPropertiesTags(object objectToConvert, ConvertMode mode)
            {
                if (objectToConvert == null)
                    return;
     
                var enumerable = objectToConvert as IEnumerable;
                if (enumerable != null)
                    foreach (var item in enumerable)
                    {
                        ConvertStringPropertiesTags(item, mode);
                        return;
                    }
     
                PropertyInfo[] properties = objectToConvert.GetType().GetProperties();
                foreach (PropertyInfo property in properties)
                {
                    object propertyValue = property.GetValue(objectToConvert, null);
                    if ((propertyValue as IEnumerable) != null && (propertyValue as IEnumerable) is ICollection)
                        ConvertStringPropertiesTags(propertyValue, mode);
     
                    if (property.PropertyType != typeof(string))
                        continue;
     
                    if (propertyValue != null && property.GetSetMethod() != null)
                        property.SetValue(objectToConvert, GetTransformations(propertyValue.ToString(), mode), null);
                }
            }
        }
    J'ai du régler un problème de réferences circulaires lié a EntityFramework entre instance encapsulente et instance encapsulée (qui encapsule l'encapsulente)...

    Il me reste un dernier pbm lié à la vue cette fois :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
        @if (Model.History != null)
        {
            <fieldset>
                <legend>Histoire du personnage</legend>
                <div class="display-field">
                    <table width="100%">
                        @foreach (var historicalEvent in Model.History)
                        {
                            <tr>
                                <td style="width: 10%">
                                    @historicalEvent.StandartYear
                                </td>
                                <td style="width: 90%">
                                    @historicalEvent.Description
                                </td>
                            </tr>
                        }
                    </table>
                </div>
            </fieldset>
        }
    ma description est du HTML (grace aux remplacements faits avec notre méthode) et je en sais pas trop comment l'afficher correctement les Html.Display... ne semblent pas pouvoir utiliser historicalEvent...

  8. #8
    Membre émérite Avatar de kheironn
    Homme Profil pro
    Chef de projets technique C# / MVC / .Net
    Inscrit en
    Février 2007
    Messages
    822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projets technique C# / MVC / .Net
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2007
    Messages : 822
    Par défaut
    J'ai retrouvé la syntaxe dans ce tutoriel :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    @Html.DisplayTextFor(modelItem => historicalEvent.Description)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème avec la récursivité
    Par mohsenuss91 dans le forum Débuter avec Java
    Réponses: 2
    Dernier message: 06/12/2013, 22h33
  2. Problème jointure (est-elle possible ?)
    Par Ludix_ dans le forum Langage SQL
    Réponses: 10
    Dernier message: 19/04/2012, 16h28
  3. [Flex/Bison] problème avec la récursivité
    Par la_praline dans le forum Autres éditeurs
    Réponses: 2
    Dernier message: 09/09/2008, 13h41
  4. Problème de reflexion
    Par lowkey dans le forum SQL Procédural
    Réponses: 1
    Dernier message: 15/11/2007, 09h58
  5. Problème de requêtes imbriquées, possible sous Access ?
    Par PierrePM dans le forum Requêtes et SQL.
    Réponses: 17
    Dernier message: 14/11/2007, 19h45

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo