using System;

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
 
namespace AttributeTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Type typeTestPropertyAttribute = Type.GetType("AttributeTest.TestPropertyAttribute");
 
            //另一种获取属性值的方法
            //此处获取的具体是哪些信息,可以通过变换类进行实现,比如此处是MemberInfo就是获取全部,可以替换为PropertyInfo,只是获取属性的特性
            foreach (MemberInfo propertyInfo in typeTestPropertyAttribute.GetMembers())
            {
                foreach (Attribute myAttribute in propertyInfo.GetCustomAttributes(true))
                {
                    PropertyTestAttribute test = myAttribute as PropertyTestAttribute;
                    if (test != null)
                    {
                        Console.WriteLine(test.PropertyAlias.ToString());
                    }
                }
            }
 
            //这是另外一种获取属性值的方法
            //Dictionary<MemberInfo, PropertyTestAttribute> dic = GetProperty(typeTestPropertyAttribute);
            //foreach (KeyValuePair<MemberInfo, PropertyTestAttribute> a in dic)
            //{
            //    Console.WriteLine(a.Key);
            //    Console.WriteLine(a.Value.PropertyAlias);
            //}
 
            Console.ReadLine();
        }
 
        public static Dictionary<MemberInfo, PropertyTestAttribute> GetProperty(Type t)
        {
            Dictionary<MemberInfo, PropertyTestAttribute> dict = new Dictionary<MemberInfo, PropertyTestAttribute>();
            //得到全部类的公共成员
            MemberInfo[] mis = t.GetMembers();
            if (mis == null || mis.Length == 0)
                return dict;
 
            //遍历成员信息表
            foreach (MemberInfo mi in mis)
            { 
                //MemberTypes是一个枚举
                //    Constructor = 1,
                //    Event = 2,
                //    Field = 4,
                //    Method = 8,
                //    Property = 16,
                //    TypeInfo = 32,
                //    Custom = 64,
                //    NestedType = 128,
                //    All = 191,
 
                //在这里可以决定获取的具体是哪些信息,比如此处是属性和字段信息,想要获取其他信息的话添加需要的枚举条件
                if((mi.MemberType!=MemberTypes.Property) && (mi.MemberType!=MemberTypes.Field))
                    continue;
                //得到自定义属性信息
                PropertyTestAttribute[] attribs = (PropertyTestAttribute[])mi.GetCustomAttributes(typeof(PropertyTestAttribute), false);
                if ((attribs == null) || (attribs.Length == 0))
                    continue;
                dict.Add(mi, attribs[0]);
            }
            return dict;
        }
    }
 
    /// <summary>
    ///自定义的一个属性类
    ///
    ///AttributeUsage参数介绍:
    ///属性 AttributeUsage 提供声明属性的基础机制
    ///ValidOn:
    //指定可以将属性赋给的程序元素(类、方法、属性、参数等)。该参数的有效值可以在 .NET Framework
    ///中的 System.Attributes.AttributeTargets   枚举中找到。该参数的默认值是所有程序元素 (AttributeElements.All)
    ///AllowMultiple:单一用途和多用途属性
    ///可以使用AttributeUsage定义属性的单一用途或多用途。即确定在单个字段上使用单一属性的次数。在缺省情况下,所有
    ///属性都是单用途的。在AttributeUsage属性中,指定AllowMultiple为true,则允许属性多次附加到指定的类型上
    ///Inherited:指定继承属性规则
    ///在AttributeUsageAttribute属性的最后部分是继承标志,用于指定属性是否能被继承。缺省值是false。然而,若继承标志
    ///被设置为true,它的含义将依赖于AllowMultiple标志的值。若继承标志被设置为true,并且AllowMultiple标志是flag,则
    ///改属性将忽略继承属性。若继承标志和AllowMultiple标志都被设置为true,则改属性的成员将与派生属性的成员合并   
    /// </summary>
    [AttributeUsage(AttributeTargets.Property|AttributeTargets.Field,Inherited=false,AllowMultiple=false)]
    public sealed class PropertyTestAttribute:Attribute
    {
        readonly string mPropertAlias;
 
        private bool isAutoIncrement;
 
        public PropertyTestAttribute(string propertyAlias)
        {
            mPropertAlias=propertyAlias;
        }
 
        public string PropertyAlias
        {
            get
            {
                return mPropertAlias;
            }
        }
 
        /// <summary>
        /// 是否自动增长。
        /// </summary>
        public bool IsAutoIncrement
        {
            get { return this.isAutoIncrement; }
            set { this.isAutoIncrement = value; }
        }
    }
 
    /// <summary>
    /// 一个作为测试的含有特性的类
    /// </summary>
    public class TestPropertyAttribute
    {
        public TestPropertyAttribute() { }
 
        private string mMyProperty;
 
        [PropertyTest("测试的字段的描述")]
        public int i;
 
        [PropertyTest("测试的属性的描述",IsAutoIncrement=true)]
        public string MyProperty
        {
            get
            {
                return mMyProperty;
            }
            set
            {
                mMyProperty = value;
            }
        }
    }
}
更加详细的介绍,可以参考颜昌刚的博客: http://www.cnblogs.com/yanchanggang/archive/2008/01/04/1025565.html