Geek Quizz XI: reflection ?


Comment récupérer et afficher les descriptions “Coucou” et “Salut” des méthodes Method1 et Method2 ?
Le code doit être générique quelque soit la nom de la méthode (Method1 ou Method2 ou autre) bien sûr !


public class Test
{
[Description(
Coucou)]
public void Method1()
{
ShowDescription(
?);
}
[Description(
Salut)]
public void Method2()
{
ShowDescription(
?);
}
public void ShowDescription(?)
{
Console.WriteLine(
?);
}
}

Comments (15)

  1. Sinon pour un code faisant totalement sans le nom de la méthode, comme ça :

    public class Test

    {

     [Description("Coucou")]

     public void Method1()

     {

       ShowDescription(((DescriptionAttribute)(new StackTrace().GetFrame(0).GetMethod().GetCustomAttributes(typeof(DescriptionAttribute), false)[0])).Description);

     }

     [Description("Salut")]

     public void Method2()

     {

       ShowDescription(((DescriptionAttribute)(new StackTrace().GetFrame(0).GetMethod().GetCustomAttributes(typeof(DescriptionAttribute), false)[0])).Description);

     }

     public void ShowDescription(string description)

     {

       Console.WriteLine(description);

     }

    }

  2. Ou encore mieux :

    public class Test

    {

     [Description("Coucou")]

     public void Method1()

     {

       ShowDescription();

     }

     [Description("Salut")]

     public void Method2()

     {

       ShowDescription();

     }

     public void ShowDescription()

     {

       try

       {

         Console.WriteLine(((DescriptionAttribute)(new StackTrace().GetFrame(1).GetMethod().GetCustomAttributes(typeof(DescriptionAttribute), false)[0])).Description);

       }

       catch

       {

         Console.WriteLine("Pas de description");

       }

     }

    }

  3. Miiitch says:

       public class Test

       {

           [Description("Coucou")]

           public void Method1()

           {

               ShowDescription();

           }

           [Description("Salut")]

           public void Method2()

           {

               ShowDescription();

           }

           private void ShowDescription()

           {

               StackTrace trace = new StackTrace();

               StackFrame caller = trace.GetFrames()[1];

               MethodBase methodBase = caller.GetMethod();

               DescriptionAttribute[] atts = methodBase.GetCustomAttributes(typeof(DescriptionAttribute), false) as DescriptionAttribute[];

               if ((atts != null) && (atts.Length > 0))

               {

                   Console.WriteLine(atts[0].Description);

               }

           }

       }

  4. mcarbenay says:

    En solution "basique", il y a l’utilisation d’un delegate :

       public class Test

       {

           delegate void AMethod();

           [Description("Coucou")]

           public void Method1()

           {

               ShowDescription(new AMethod(Method1));

           }

           [Description("Salut")]

           public void Method2()

           {

               ShowDescription(new AMethod(Method2));

           }

           public void ShowDescription(Delegate g)

           {

               object[] obj = g.Method.GetCustomAttributes(typeof(DescriptionAttribute), false);

               Console.WriteLine(obj != null && obj.Length > 0 ? (obj[0] as DescriptionAttribute).Description : "");

           }

       }

  5. Petit commentaire :

    methodBase.GetCustomAttributes(typeof(DescriptionAttribute), false) ne renvoit pas un tableau de DescriptionAttribute. C’est quand même vraiment dommage. D’où l’intérêt d’une petite extension method : http://www.codeplex.com/ExtensionMethods

  6. Mitsu Furuta says:

    Sinon on peut faire: methodBase.GetCustomAttributes(typeof(DescriptionAttribute), false).OfType<DescriptionAttribute>()

  7. Mitsu Furuta says:

    Toutes vos suggestions sont très intéressantes mais je pensais à quelquechose de bien plus court. J’attends encore quelques autres suggestions.

    Michael, bien que l’idée de passer par un délégué pour récupérer la MethodInfo soit assez smart, je cherche une méthode générique pour récupérer les informations de type or tu utilises Method1 en dur dans ton code. Du coup autant faire directement typeof(Test).GetMethod("Method1").

  8. Ca peut-être mais c’est pas beaucoup plus court :

    public class Test

    {

     [Description("Coucou")]

     public void Method1()

     {

       ShowDescription(MethodBase.GetCurrentMethod());

     }

     [Description("Salut")]

     public void Method2()

     {

       ShowDescription(MethodBase.GetCurrentMethod());

     }

     public void ShowDescription(MethodBase mb)

     {

       DescriptionAttribute descriptionAttribute = DescriptionAttribute.GetCustomAttribute(mb, typeof(DescriptionAttribute)) as DescriptionAttribute;

       Console.WriteLine(descriptionAttribute != null ? descriptionAttribute.Description : "" );

     }

    }

  9. cyril says:

       class Program

       {

           static void Main(string[] args)

           {

               Test();

               Console.ReadLine();

           }

           [Description("toto")]

           public static void Test()

           {

               GetDescription(MethodInfo.GetCurrentMethod());

           }

           static void GetDescription(MethodBase mb)

           {

               Console.WriteLine(((DescriptionAttribute)Attribute.GetCustomAttribute(mb, typeof(DescriptionAttribute))).Description);

           }

       }

  10.        [Description("Coucou")]

           public void Method1()

           {

               MethodInfo mi = DynamicMethod.GetCurrentMethod() as MethodInfo;

               ShowDescription(mi);

           }

           [Description("Salut")]

           public void Method2()

           {

               MethodInfo mi = DynamicMethod.GetCurrentMethod() as MethodInfo;

               ShowDescription(mi);

           }

           public void ShowDescription(MethodInfo mi)

           {

               DescriptionAttribute da = Attribute.GetCustomAttribute(mi, typeof(DescriptionAttribute)) as DescriptionAttribute;

               Console.WriteLine(da.Description);

           }

    J’ai du mal à faire plus court :))

    Sébastien Pertus

  11. cyril says:

    J’ai l’impression que ma réponse n’est pas passé :-/

    je la remet :p

       class Program

       {

           static void Main(string[] args)

           {

               Test();

               Console.ReadLine();

           }

           [Description("toto")]

           public static void Test()

           {

               GetDescription(MethodInfo.GetCurrentMethod());

           }

           static void GetDescription(MethodBase mb)

           {  

               // j’ai un peu oublié de gerer les exceptions :p

               Console.WriteLine(((DescriptionAttribute)Attribute.GetCustomAttribute(mb, typeof(DescriptionAttribute))).Description);

           }

       }

  12. Je ne trouve pas ça forcément mieux mais j’essaie 🙂

    public class Test

    {

       [Description("Coucou")]

       public void Method1()

       {

           ShowDescription(MethodBase.GetCurrentMethod());

       }

       [Description("Salut")]

       public void Method2()

       {

           ShowDescription(MethodBase.GetCurrentMethod());

       }

       public void ShowDescription(MemberInfo mi)

       {

           DescriptionAttribute description = Attribute.GetCustomAttribute(mi, typeof(DescriptionAttribute)) as DescriptionAttribute;

           if (description != null)

               Console.WriteLine(description.Description);

       }

    }

  13. Roshdy says:

    Là tous les points d’interrogation sont alimentés!  Reste à savoir si c’est la plus courte … pour l’utilisation de  linq à la limite inutile, mais bon c’était pour s’habituer aux bonnes habitudes 😀

    Je ne passe pas par StackTrace mais directment par MethodBase et ses static methods !

    public class Test

       {

           [Description("Coucou")]

           public void Method1()

           {

               ShowDescription(MethodBase.GetCurrentMethod());

           }

           [Description("Salut")]

           public void Method2()

           {

               ShowDescription(MethodBase.GetCurrentMethod());

           }

           private void ShowDescription(MethodBase mBase)

           {

               var q = from des in mBase.GetCustomAttributes(typeof(DescriptionAttribute),false)

                       select (des as DescriptionAttribute).Description;

               Console.WriteLine(q.ToList<string>().Count == 0 ? "Désolé pas de descrption " : q.ToList<string>()[0]);

           }

       }

  14. Mitsu Furuta says:

    Stop stop stop ! C’est bon vous avez tous gagné ! :p

    En effet j’attendais la solution utilisant MethodInfo.GetCurrentMethod(). Une solution simple d’une méthode étrange qui rappelle la méthode courante. L’utilisation de stacktrace est identique.

    Mitsu

    PS: au fait désolé pour les commentaires bloqués mais mon moteur de blog est subitement devenu paranoïaque a tout passé en “Possible spam”..