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

VB.NET Discussion :

[Réflection] Lister et modifier des propriétés


Sujet :

VB.NET

  1. #1
    Membre expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Points : 3 545
    Points
    3 545
    Par défaut [Réflection] Lister et modifier des propriétés
    Bonjour,

    J'ai un problème avec la réflection, que je ne sais pas trop utiliser.

    J'ai deux objets métiers que j'aimerais comparer pour fusionner les données : obj1 et obj2.

    Le principe est d'alimenter une propriété de obj1 avec la valeur de la même propriété de obj2 lorsque la première est vide.

    Je précise tout d'abord que je ne cherche pas à itérer sur toutes les propriétés, seulement sur celles que je spécifie.

    Afin de ne pas trop coder, l'idée est d'appeler une méthode de fusion pour chaque propriété désirée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    private sub Fusion(byval strNomPropriete)
    'ici le code de réflection
    end sub
    appelée ensuite comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    call Fusion("identifiant")
    call Fusion("nom")
    call Fusion("prenom")
    Cette méthode devra trouver la valeur de la propriété dans obj1 et attribuer la valeur de la même propriété de obj2 si la première est vide. Je me répète, mais ce n'est sûrement pas du luxe.

    obj1 et obj2 sont évidemment accessibles dans toute la classe.

    Passons aux questions :

    - comment obtenir la valeur de strNomPropriete ?
    - comment changer cette valeur ?

    Merci de votre aide.
    • Avant de poser une question, n'hésitez pas à chercher dans la FAQ et les forums
    • Merci d'utiliser les balises de code (# dans l'éditeur)
    • N'oubliez pas de vous servir des boutons , et

    S.N.A.F.U

  2. #2
    Membre expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Points : 3 545
    Points
    3 545
    Par défaut
    J'ai commencé à chercher, mais c'est pas glorieux :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Dim member As System.Reflection.PropertyInfo
    member = obj1.GetType.GetProperty("identifiant", reflection.BindingFlags.CreateInstance)
    member reste à "nothing"

    • Avant de poser une question, n'hésitez pas à chercher dans la FAQ et les forums
    • Merci d'utiliser les balises de code (# dans l'éditeur)
    • N'oubliez pas de vous servir des boutons , et

    S.N.A.F.U

  3. #3
    Membre expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Points : 3 545
    Points
    3 545
    Par défaut
    Toujours pas de réponse ?
    Ma question était sûrement un peu fouilli...

    J'essaie de commencer par plus simple :

    J'ai un objet obj avec deux propriétés : "id" et "nom".
    Ces deux propriétés sont en read-write.

    Comment lire la valeur de "id" et modifier la valeur de "nom" en utilisant la réflection ?

    Merci
    • Avant de poser une question, n'hésitez pas à chercher dans la FAQ et les forums
    • Merci d'utiliser les balises de code (# dans l'éditeur)
    • N'oubliez pas de vous servir des boutons , et

    S.N.A.F.U

  4. #4
    Membre expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Points : 3 545
    Points
    3 545
    Par défaut
    Bon, bah j'ai trouvé tout seul, comme un grand.
    Si jamais ça intéresse du monde, voilà le truc :

    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
     
        Public Sub Fusionner(ByVal oMaster As clsMonZobjet, ByVal oSlave As clsMonZobjet)
            If oMaster Is Nothing Then Exit Sub
            If oSlave Is Nothing Then Exit Sub
     
            Call FusionChaine(oMaster, oSlave, "Nom")
            Call FusionChaine(oMaster, oSlave, "Prenom")
     
            oMaster.DtMaj = Date.Now
            oSlave.Supprimer()
        End Sub
     
        Private Sub FusionChaine(ByVal o1 As clsMonZobjet, ByVal o2 As clsMonZobjet, ByVal propertyName As String)
            Dim p1 As System.Reflection.PropertyInfo = o1.GetType().GetProperty(propertyName)
            Dim p2 As System.Reflection.PropertyInfo = o2.GetType().GetProperty(propertyName)
            ' une des deux objets est null => aucune action
            If p1 Is Nothing Or p2 Is Nothing Then Exit Sub
     
            Dim v1 As String = p1.GetValue(o1, Nothing).ToString
            Dim v2 As String = p2.GetValue(o2, Nothing).ToString
     
            ' valeur du slave nulle => aucun fusion à faire
            If v2 = String.Empty Then Exit Sub
     
            ' valeur du master nulle => FUSION ! (reférénce à dragonball Z ;)
            If v1 = String.Empty Then p1.SetValue(o1, v2, Nothing)
        End Sub
    • Avant de poser une question, n'hésitez pas à chercher dans la FAQ et les forums
    • Merci d'utiliser les balises de code (# dans l'éditeur)
    • N'oubliez pas de vous servir des boutons , et

    S.N.A.F.U

  5. #5
    Membre habitué
    Inscrit en
    Janvier 2007
    Messages
    201
    Détails du profil
    Informations personnelles :
    Âge : 79

    Informations forums :
    Inscription : Janvier 2007
    Messages : 201
    Points : 154
    Points
    154
    Par défaut
    Merci Jml94, ton sujet m'avait vraiment interesse, mais ne pouvant pas faire avancer le chmilblick j'avais prefere me taire.
    As tu trouve une doc pour resoudre le probleme ? Si oui un petit lien ?
    Sinon bravo.
    Cordialement
    Belocom

  6. #6
    Rédacteur
    Avatar de SaumonAgile
    Homme Profil pro
    Team leader
    Inscrit en
    Avril 2007
    Messages
    4 028
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Team leader
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2007
    Messages : 4 028
    Points : 6 334
    Points
    6 334
    Par défaut
    Etant donné que les propertyInfo ne sont pas dépendants d'une instance mais d'un type, je pense que tu peux t'epargner la peine d'en instancier deux, et utiliser le même pour récupérer la valeur sur tes deux objets.

    Si tu sais déjà que tu vas récupérer une variable de type string avec le GetValue(), pourquoi ne pas faire un cast directement plutot que d'appeler ToString() sur l'Object retourné ?
    Besoin d'un MessageBox amélioré ? InformationBox pour .NET 1.1, 2.0, 3.0, 3.5, 4.0 sous license Apache 2.0.

    Bonnes pratiques pour les accès aux données
    Débogage efficace en .NET
    LINQ to Objects : l'envers du décor

    Mon profil LinkedIn - MCT - MCPD WinForms - MCTS Applications Distribuées - MCTS WCF - MCTS WCF 4.0 - MCTS SQL Server 2008, Database Development - Mon blog - Twitter

  7. #7
    Membre expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Points : 3 545
    Points
    3 545
    Par défaut
    Citation Envoyé par SaumonAgile
    Etant donné que les propertyInfo ne sont pas dépendants d'une instance mais d'un type, je pense que tu peux t'epargner la peine d'en instancier deux, et utiliser le même pour récupérer la valeur sur tes deux objets.
    Sûrement, mais est-ce une optimisation qui vaut le coup ?
    Je veux dire que ça tuerais la lisibilité pour un gain de perf négligeable.

    Citation Envoyé par SaumonAgile
    Si tu sais déjà que tu vas récupérer une variable de type string avec le GetValue(), pourquoi ne pas faire un cast directement plutot que d'appeler ToString() sur l'Object retourné ?
    Il me semble qu'un ToString ou caster en chaîne, c'est plus ou moins la même chose...

    J'utilise une fonction spécifique de chaîne, car j'en ai aussi une pour les propriétés de format date, que je n'ai pas copié ici.
    Le principe est le même, mais j'ai une gestion métier spécifique des dates.
    • Avant de poser une question, n'hésitez pas à chercher dans la FAQ et les forums
    • Merci d'utiliser les balises de code (# dans l'éditeur)
    • N'oubliez pas de vous servir des boutons , et

    S.N.A.F.U

  8. #8
    Rédacteur
    Avatar de SaumonAgile
    Homme Profil pro
    Team leader
    Inscrit en
    Avril 2007
    Messages
    4 028
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Team leader
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2007
    Messages : 4 028
    Points : 6 334
    Points
    6 334
    Par défaut
    Oui l'optimisation vaut le coût, la reflexion est un processus assez couteux.

    Concernant le tostring(), imagine ce qui se passe si la propriété que tu recherches n'est pas de type string mais de type double. Je vois beaucoup trop souvent des Double.Parse(Object.toString() au lieu de Convert.ToDouble(Object) ou même (double) Object. Effectivement pour un string, ça change peu de choses, mais je pense au cas général.
    Besoin d'un MessageBox amélioré ? InformationBox pour .NET 1.1, 2.0, 3.0, 3.5, 4.0 sous license Apache 2.0.

    Bonnes pratiques pour les accès aux données
    Débogage efficace en .NET
    LINQ to Objects : l'envers du décor

    Mon profil LinkedIn - MCT - MCPD WinForms - MCTS Applications Distribuées - MCTS WCF - MCTS WCF 4.0 - MCTS SQL Server 2008, Database Development - Mon blog - Twitter

  9. #9
    Membre expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Points : 3 545
    Points
    3 545
    Par défaut
    Citation Envoyé par SaumonAgile
    Oui l'optimisation vaut le coût, la reflexion est un processus assez couteux.
    Pour l'instant, je ne fusionne qu'au cas par cas, choisi manuellement dans l'IHM.
    Mais c'est vrai que je prévois un traitement de fusion/dédoublonnage automatique pour lequel une optimisation serait peut-être utile.
    A tester.

    Citation Envoyé par SaumonAgile
    Concernant le tostring(), imagine ce qui se passe si la propriété que tu recherches n'est pas de type string mais de type double. Je vois beaucoup trop souvent des Double.Parse(Object.toString() au lieu de Convert.ToDouble(Object) ou même (double) Object. Effectivement pour un string, ça change peu de choses, mais je pense au cas général.
    Pas fauux du tout, je vais penser à protéger mon code. Merci pour cette remarque fort pertinente !
    • Avant de poser une question, n'hésitez pas à chercher dans la FAQ et les forums
    • Merci d'utiliser les balises de code (# dans l'éditeur)
    • N'oubliez pas de vous servir des boutons , et

    S.N.A.F.U

  10. #10
    Membre expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Points : 3 545
    Points
    3 545
    Par défaut
    Je viens de découvrir la fonction CallByName qui à l'air beaucoup plus simple à lire : http://msdn2.microsoft.com/fr-fr/lib...x6(VS.80).aspx

    Elle utilise sûrement la réflection.

    Je vais tester ce soir.
    • Avant de poser une question, n'hésitez pas à chercher dans la FAQ et les forums
    • Merci d'utiliser les balises de code (# dans l'éditeur)
    • N'oubliez pas de vous servir des boutons , et

    S.N.A.F.U

  11. #11
    Membre expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Points : 3 545
    Points
    3 545
    Par défaut
    Ca marche.
    Et ça donne un code un peu plus lisible :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        Private Sub FusionChaine(ByVal o1 As clsUneEntreprise, ByVal o2 As clsUneEntreprise, ByVal propertyName As String)
            Dim v1 As String = CallByName(o1, propertyName, CallType.Get).ToString
            Dim v2 As String = CallByName(o2, propertyName, CallType.Get).ToString
            If v2 = String.Empty Then Exit Sub
            If v1 = String.Empty Then CallByName(o1, propertyName, CallType.Set, v2)
        End Sub
    Evidemment, il reste le problème de protéger l'accès lorsque la variable n'est pas vraiment une chaîne, mais c'est une autre question...
    • Avant de poser une question, n'hésitez pas à chercher dans la FAQ et les forums
    • Merci d'utiliser les balises de code (# dans l'éditeur)
    • N'oubliez pas de vous servir des boutons , et

    S.N.A.F.U

  12. #12
    Rédacteur
    Avatar de SaumonAgile
    Homme Profil pro
    Team leader
    Inscrit en
    Avril 2007
    Messages
    4 028
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Team leader
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2007
    Messages : 4 028
    Points : 6 334
    Points
    6 334
    Par défaut
    Si tu utilises le framework 2.0, la méthode conseillée pour tester les string est d'utiliser la méthode String.IsNullOrEmpty(string) à la place de string == String.Empty.

    En passant tes assembly dans fxcop, tu peux (comme moi) découvrir pas mal d'astuces de lisibilité et de maintenabilité.
    Besoin d'un MessageBox amélioré ? InformationBox pour .NET 1.1, 2.0, 3.0, 3.5, 4.0 sous license Apache 2.0.

    Bonnes pratiques pour les accès aux données
    Débogage efficace en .NET
    LINQ to Objects : l'envers du décor

    Mon profil LinkedIn - MCT - MCPD WinForms - MCTS Applications Distribuées - MCTS WCF - MCTS WCF 4.0 - MCTS SQL Server 2008, Database Development - Mon blog - Twitter

  13. #13
    Membre expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Points : 3 545
    Points
    3 545
    Par défaut
    Merci de cette précision, je vais aller voir la littérature pour me coucher moins con ce soir !
    • Avant de poser une question, n'hésitez pas à chercher dans la FAQ et les forums
    • Merci d'utiliser les balises de code (# dans l'éditeur)
    • N'oubliez pas de vous servir des boutons , et

    S.N.A.F.U

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

Discussions similaires

  1. Modifier les propriétés des documents office
    Par justgreat dans le forum VB 6 et antérieur
    Réponses: 0
    Dernier message: 02/05/2010, 15h31
  2. Modifier les propriétés des composants d'une autre form
    Par souminet dans le forum Débuter
    Réponses: 3
    Dernier message: 20/08/2008, 09h09
  3. modifier des propriétés dans vba
    Par 4rocky4 dans le forum VBA Access
    Réponses: 12
    Dernier message: 05/02/2008, 11h42
  4. Réponses: 2
    Dernier message: 09/11/2007, 15h18
  5. Lire et modifier les propriétés des fichiers Office
    Par SilkyRoad dans le forum Contribuez
    Réponses: 4
    Dernier message: 18/09/2006, 22h25

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