Archive

Posts Tagged ‘Reflection’

Reflection and Custom Attributes

November 1, 2010 Leave a comment

If you need to annotate your methods with custom attributes and would like to determine which classes and methods use the attribute at run-time then you need to use GetCustomAttributes() method in .NET. Below is some C# code showing how this is done.

using System;
using System.Linq;
using System.Reflection;

namespace ReflectionAttributesSample
{

    [AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = true)]
    public class DescriptionAttribute : Attribute
    {
        private readonly string _description;

        public DescriptionAttribute(string description)
        {
            _description = description;
        }

        public string Description
        {
            get { return _description; }
        }
    }

    [Description("Class Name Main")]
    class Program
    {

        [Description("Instance Method Named Print")]
        public void Print(){}

        [Description("Private Static Method Named Main")]
        static void Main()
        {

            /*
             * 
             * Get attributes from a specific class / struct type of a specific attribute type
             * 
             */

            Type t = typeof (Program);
            var descriptionattributes = t.GetCustomAttributes(typeof (DescriptionAttribute), false);

            foreach (DescriptionAttribute attr in descriptionattributes)
                Console.WriteLine(attr.Description);

            /*
             * 
             * Get attributes from a specific method of a specific attribute type
             * 
             */

            foreach(DescriptionAttribute attr in 
                t.GetMethod("Main", BindingFlags.NonPublic | BindingFlags.Static).GetCustomAttributes(typeof (DescriptionAttribute), false))
                Console.WriteLine(attr.Description);

            /*
             * 
             * Get attributes from all of a specific attribute type
             * 
             */

            foreach (MethodInfo attr in t.GetMethods(BindingFlags.NonPublic | BindingFlags.Public |  
                BindingFlags.Static | BindingFlags.Instance))
            {
                var descattrs = attr.GetCustomAttributes(typeof (DescriptionAttribute), false);
                if(!descattrs.Any())
                    continue;

                Console.WriteLine("Method: {0} - {1}",attr.Name,((DescriptionAttribute)(descattrs[0])).Description);
            }


            Console.WriteLine("Press any key to quit");
            Console.ReadKey();
        }
    }
}

Blair..

Advertisements

Generics and Reflection .NET with C#

July 24, 2010 Leave a comment

Generics in .NET work a little differently depending that normal reflection over types. The difference appears in whether the type is an open type, no type arguments supplied or a closed type all type arguments supplied.

static void Main()
        {
            Type opentype = typeof (List<>);
            
            Console.WriteLine("Name: " + opentype.FullName);
            Console.WriteLine("Is Generic Type: " + opentype.IsGenericType);
            Console.WriteLine("Contains Generic Parameters: " + opentype.ContainsGenericParameters);

            Console.WriteLine();

            Type closedtype = typeof(List<Person>);

            Console.WriteLine("Name: " + closedtype.FullName);
            Console.WriteLine("Is Generic Type: " + closedtype.IsGenericType);
            Console.WriteLine("Contains Generic Parameters: " + closedtype.ContainsGenericParameters);
            Console.WriteLine("Type Arguments are as follows...");
            Array.ForEach(closedtype.GetGenericArguments(), Console.WriteLine);

            Console.ReadKey();
        }

The output is as follows..
Name: System.Collections.Generic.List`1
Is Generic Type: True
Contains Generic Parameters: True
Name: System.Collections.Generic.List`1[[CSharpSamples.Person, CSharpSamples, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]
Is Generic Type: True
Contains Generic Parameters: False
Type Arguments are as follows…
CSharpSamples.Person

The first line shows System.Collections.Generic.List`1, which means there is 1 type parameters. This is also an open type as Person has not been supplied as a type argument as opposed to System.Collections.Generic.List`1[[CSharpSamples.Person, CSharpSamples, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].

Also the type is generics as show by the second line and contain un supplied type arguments as shown on the third line.

The final line GetGenericArguments() allows you to get all supplied type arguments.

Hope this helps…

Blair