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 :

Fonction .NET pour récupérer le nom de la procédure en cours


Sujet :

VB.NET

  1. #1
    Membre actif
    Inscrit en
    Juillet 2013
    Messages
    777
    Détails du profil
    Informations forums :
    Inscription : Juillet 2013
    Messages : 777
    Points : 275
    Points
    275
    Par défaut Fonction .NET pour récupérer le nom de la procédure en cours
    Bonjour,
    Je souhaiterais créer une sub qui aurait en argument le nom de la procédure dans laquelle elle est appelée.
    Mais comme je compte faire des appels dans plein de procédures. J'aimerais éviter d'avoir à "personnaliser" l'argument à chaque fois.

    Au lieu d'écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    sub toto1()
    Maprocedure("toto1")
    end sub
     
    sub toto2()
    Maprocedure("toto2")
    end sub
     
    ...
    je voudrais quelques chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    sub toto1()
    Maprocedure(methode)
    end sub
     
    sub toto2()
    Maprocedure(methode)
    end sub
     
    ...
    où methode est une instruction .NET qui trouve automatiquement le nom de la procédure dans laquelle elle est utilisée.
    Le but est de pouvoir faire des copier/coller rapidement...

    Est-ce qu'une telle méthode existe ?

    Sur le Net je n'ai rien trouvé.

  2. #2
    Expert confirmé
    Avatar de wallace1
    Homme Profil pro
    Administrateur systèmes
    Inscrit en
    Octobre 2008
    Messages
    1 966
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Administrateur systèmes
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 966
    Points : 4 005
    Points
    4 005
    Billets dans le blog
    7
    Par défaut
    Bonsoir,

    Lorsqu'il s'agit d'inspecter dynamiquement une assembly on utilise "Reflection" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Imports System.Reflection
     
    '......
    '........
    sub toto1()
        Maprocedure(System.Reflection.MethodBase.GetCurrentMethod().Name)
    end sub
     
    '......
    '........

    A+

  3. #3
    Membre actif
    Inscrit en
    Juillet 2013
    Messages
    777
    Détails du profil
    Informations forums :
    Inscription : Juillet 2013
    Messages : 777
    Points : 275
    Points
    275
    Par défaut
    Super,
    Un grand merci.
    J'avais pourtant cherché du coté de system.reflection mais je n'avais pas trouvé. C'est balot !

  4. #4
    Membre chevronné
    Avatar de Sehnsucht
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2008
    Messages
    847
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2008
    Messages : 847
    Points : 2 209
    Points
    2 209
    Par défaut
    Pour ceux utilisant au moins VS2012 (et donc les dernières versions des compilateurs C#/VB.Net) il existe une alternative plus qu'intéressante ; à savoir CallerMemberName (il existe aussi CallerFilePath et CallerLinerNumber au besoin)

    Ses avantages sont multiples, déjà une fois en place, ce n'est plus à celui utilisant la méthode (MaProcédure ici) de passer la bonne chose, cela se fait automatiquement, ensuite par exemple en cas d'utilisation de la méthode évoquée par wallace1 avec une propriété on obtiendra "get_NomProp" (ou "set_NomProp" selon si c'est sur l'accesseur ou le mutateur) chose qui n'est pas toujours ce que l'on souhaitait ; enfin, comme tout ce qui réside dans l'espace de noms System.Runtime.CompilerServices ; c'est à la compilation que se fait le boulot donc aucun surcoût à l'exécution contrairement à la Reflection dont parfois le coût est loin d'être négligeable.

    Comment ça fonctionne ? c'est simple, à la compilation, le code est réécrit et l'argument utilisant CallerMemberName est remplacé par la bonne valeur directement dans le code (comme si on l'avait passé nous-mêmes) mais c'est fait automatiquement et de manière transparente donc même si on change le nom un jour, après recompilation le nouveau nom sera lui-aussi présent dans l'appel.

    Comment on l'utilise ? on marque juste l'argument de notre procédure avec l'attribut CallerMemberName ; seules contraintes, cet argument doit être de type String (normal) ET être optionnel :
    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
    ' Imports System.Runtime.CompilerServices
     
    Sub MaProcedure (<CallerMemberName> Optional memberName As String = "")
       ' utilisation de memberName qui contient le nom de l'appelant
    End Sub
     
    ' exemples d'utilisation
    Sub Toto1 ()
        MaProcedure () 'on ne passe rien c'est le compilo qui s'en chargera (d'où la nécessité du paramètre optionnel)
        ' après compilation le code sera comme ceci
        ' MaProcedure ("Toto1")
    End Sub
     
    ReadOnly Property Foo As Integer
        Get
            MaProcedure () ' même principe avec une propriété
            ' après compilation :
            ' Maprocedure ("Foo")
            Return 42
        End Get
    End Property
    Rien n'empêche de mettre d'autres paramètres à MaProcedure (par exemple un message à passer en même temps), il faudra juste qu'il soit spécifié avant dans la liste des arguments (vu qu'une fois qu'il y a des paramètres optionnels, tous ceux qui suivent doivent l'être aussi) ; exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Sub MaProcedure (message As String, <CallerMemberName> Optionnal memberName As String = "")
        Log.Write("In {0} : {1}", memberName, message) ' exemple
    End Sub
    Par contre, une chose en garder en tête (enfin à vérifier surtout) ; c'est comment se comporte ceci dans le cadre d'une obfuscation du code ; comme le compilateur remplace l'appel en y précisant le nom de l'appelant ; et que certains obfuscateurs réécrivent le nom des méthodes, il se peut que ça donne des incohérences (ou que ce type d'appel continue d'apparaitre "en clair" chose potentielle problématique dans ce type de scénario). Après je n'ai personnellement jamais utilisé d'obfuscateurs ; si ça se trouve il gèrent très bien les choses mais dans le doute je préfère prévenir

  5. #5
    Modérateur
    Avatar de DotNetMatt
    Homme Profil pro
    CTO
    Inscrit en
    Février 2010
    Messages
    3 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : Février 2010
    Messages : 3 611
    Points : 9 743
    Points
    9 743
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par Sehnsucht Voir le message
    Par contre, une chose en garder en tête (enfin à vérifier surtout) ; c'est comment se comporte ceci dans le cadre d'une obfuscation du code ; comme le compilateur remplace l'appel en y précisant le nom de l'appelant ; et que certains obfuscateurs réécrivent le nom des méthodes, il se peut que ça donne des incohérences (ou que ce type d'appel continue d'apparaitre "en clair" chose potentielle problématique dans ce type de scénario). Après je n'ai personnellement jamais utilisé d'obfuscateurs ; si ça se trouve il gèrent très bien les choses mais dans le doute je préfère prévenir
    En effet cet article : Caller Details confirme que c'est bien le nom de substitution qui sera utilisé.

  6. #6
    Expert confirmé
    Avatar de wallace1
    Homme Profil pro
    Administrateur systèmes
    Inscrit en
    Octobre 2008
    Messages
    1 966
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Administrateur systèmes
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 966
    Points : 4 005
    Points
    4 005
    Billets dans le blog
    7
    Par défaut
    Merci Sehn c'est effectivement très intéressant ce que tu nous proposes là.

  7. #7
    Membre actif
    Inscrit en
    Juillet 2013
    Messages
    777
    Détails du profil
    Informations forums :
    Inscription : Juillet 2013
    Messages : 777
    Points : 275
    Points
    275
    Par défaut
    Merci pour cette autre méthode.
    Je m'en souviendrai si je passe sur VS 2012. Actuellement je travaille avec VS 2010 Ultimate

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

Discussions similaires

  1. Problème pour récupérer le nom d'un JLabel
    Par ropabo dans le forum AWT/Swing
    Réponses: 2
    Dernier message: 02/06/2006, 01h10
  2. Expression régulière pour récupérer le nom d'un fichier
    Par calimero2611 dans le forum Langage
    Réponses: 5
    Dernier message: 24/02/2006, 19h00
  3. Requête pour récupérer le nom des champs
    Par legillou dans le forum JDBC
    Réponses: 1
    Dernier message: 08/02/2006, 16h09
  4. [VB.NET] Comment récupérer le nom d'un control avec le focus
    Par jayce007 dans le forum Windows Forms
    Réponses: 5
    Dernier message: 20/01/2005, 00h53

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