HanDs
管理员

[Visual Studio文章] 定制自己的属性 



在未使用.net编写程序之前,如果想看自己写的一些函数的备注,就必须要找到该函数才可以看的到,利用.net里的属性和反射机制,可以很轻松的定制自己的属性,在自己的程序里使用自己定制的属性,而且可以利用反射把这些属性单独抽出来管理,这样就可以更轻松的管理我们的程序。以下的例子是我参考《C#高级编程》里的例子写的,觉得这个例子很有代表性,拿出来与大家共享,也算是抛砖引玉吧。

这个例子分三部分组成:第一部分是定制自己的属性;第二部分是在程序里使用自己定制的属性;第三部分是利用反射把程序里的属性单独抽出来。

我们如果要定义自己的属性,就得继承类Attribute,命名空间是System。还有一点需要说明的是我们在定制自己的属性时,必须说明该属性的用途,这样编译器才知道这些属性可以用在哪些地方,所以一般在属性类之前都有这样类似的代码,如下:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property,AllowMultiple = true,

 

         Inherited = false)]

 

AttributeUsage是一个类,有关它的详细用法可以参考sdk帮助文档。

 

下面我们就开始定制自己的属性,如下:(可以把它编译成dll文件,以备其他的程序使用)

 

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property,AllowMultiple = true,

 

         Inherited = false)]

 

    public class LastModified : Attribute

 

    {

 

        private DateTime _lastModified;

 

        private string _comment;

 

        private string _issues;

 


 

       

 

        public LastModified(string datetime,string comment)

 

        {

 

            this._lastModified = Convert.ToDateTime(datetime);

 

            this._comment = comment;

 

        }

 

        //说明

 

        public string Issues

 

        {

 

            get

 

            {

 

                return _issues;

 

            }

 

            set

 

            {

 

                _issues = value;

 

            }

 

        }

 

        //备注

 

        public string Comment

 

        {

 

            get

 

            {

 

                return _comment;

 

            }

 

        }

 

        //修改日期

 

        public DateTime Lastmodified

 

        {

 

            get

 

            {

 

                return _lastModified;

 

            }

 

        }

 

    }

 

下面是在自己的程序中使用自己定义的属性,记得添加自己定义属性的引用,以下是我写的一个类Account,在它的一个方法里我用到了我自己定义的属性,如下:

 

[LastModified("2005/04/06","jah programed first")]

 

        public void OutputAccount(int output)

 

        {

 

            if(output < 0)

 

            {

 

                myArgs.Balance = output;

 

                Underzero(myArgs);

 

            }

 

            else if(output > balance)

 

            {

 

                myArgs.Balance = output;

 

                Overspend(myArgs);

 

            }

 

            else

 

            {

 

                this.balance -= output;

 

            }

 

        }

 

下面我们就利用反射来把自己的属性抽取出来,在此为了快速的知道自己的程序是否支持自定义属性,我们可以在定义一个属性类,用它来检测是否支持自定义属性。代码如下:

 

[AttributeUsage(AttributeTargets.All,AllowMultiple = true,

 

         Inherited = false)]

 

    public class SupportNew : Attribute

 

    {

 


 

    }

 

这样我们就可以在Account类前面添加一行代码,说明它支持自定义属性,这样可以提高查找自定义属性的速度,代码为:[assembly:SupportNew],下面我就把第三部分的代码贴出来,如下:(记住引用上面编写好的自定义属性dll文件)为此我专门写了个类,它的功能是给定一个程序集,它就会查找所有的自定义属性,并把信息添加到一个ArrayList中。

 

using System;

 

using System.Collections;

 

using CustomAttribute;

 

using System.Reflection;

 

namespace LookUpAttribute

 

{

 

   

 

    /// <summary>

 

    /// 对于自定义的属性进行查询

 

    /// </summary>

 

    public class LookUp

 

    {

 

        private string _path;

 

        private ArrayList _list;

 

        public LookUp(string path)

 

        {

 

            _path = path;

 

            _list = new ArrayList();

 

        }

 

        /// <summary>

 

        /// 得到信息列表

 

        /// </summary>

 

        public ArrayList List

 

        {

 

            get

 

            {

 

                return _list;

 

            }

 

        }

 

        /// <summary>

 

        /// 对于给定的程序集进行处理,以便得到自定义属性

 

        /// </summary>

 

        public void DisplayAttribute()

 

        {

 

            //导入程序集

 

            Assembly myAssembly = Assembly.LoadFrom(_path);

 

            //看是否支持自定义属性

 

            Attribute supportAttribute = Attribute.GetCustomAttribute(myAssembly,typeof(SupportNew));

 

            string name = myAssembly.FullName;

 

            this.AddToMessage(name);

 

            if(supportAttribute == null)

 

            {

 

                this.AddToMessage("该程序集不支持SupportNewAttribute");

 

                return;

 

            }

 

            else

 

            {

 

                this.AddToMessage("已经定义的类型如下:");

 

            }

 

            //得到程序集的所有的类型

 

            Type[] myTypes = myAssembly.GetTypes();

 

           

 

            foreach(Type myType in myTypes)

 

            {

 

                this.DisplayTypeInfo(myAssembly,myType);

 

            }

 

        }

 

        /// <summary>

 

        /// 把信息添加到ArrayList中

 

        /// </summary>

 

        /// <param name="msg">信息</param>

 

        private void AddToMessage(string msg)

 

        {

 

            _list.Add(msg);

 

        }

 

        private void WriteAttributeInfo(Attribute attribute)

 

        {

 

            LastModified last = attribute as LastModified;

 

            if(last == null)

 

                return;

 

            this.AddToMessage("时间:"+last.Lastmodified.ToShortDateString() + " 说明:" +last.Comment );

 

        }

 

        private void DisplayTypeInfo(Assembly assembly,Type type)

 

        {

 

            //不是类则不处理

 

            if(!type.IsClass)

 

                return;

 

            this.AddToMessage("*************");

 

            this.AddToMessage("类名:"+type.Name);

 

            //类的自定义属性

 

            Attribute[] attributes = Attribute.GetCustomAttributes(type);

 

            if(attributes.Length == 0)

 

            {

 

                this.AddToMessage("该类本身没有自定义属性");

 

            }

 

            else

 

            {

 

                foreach(Attribute a in attributes)

 

                {

 

                    this.WriteAttributeInfo(a);

 

                }

 

            }

 

            BindingFlags flag = (BindingFlags.NonPublic | BindingFlags.Public |

 

                BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);

 

            MethodInfo[] methods = type.GetMethods(flag);

 

            //方法的自定义属性

 

            foreach(MethodInfo nextMethod in methods)

 

            {

 

                Object[] obj = nextMethod.GetCustomAttributes(typeof(LastModified),false);

 

                if(obj.Length > 0)

 

                {

 

                    this.AddToMessage(type.Name+":"+nextMethod.Name);

 

                    foreach(Attribute a in obj)

 

                    {

 

                        this.WriteAttributeInfo(a);

 

                    }

 

                }

 

            }

 

        }

 

    }

 

}

 

最后我演练一下如何使用这个类,如下:

 

LookUp objLookup = new LookUp(this.txtPath.Text);

 

objLookup.DisplayAttribute();

 

ArrayList array = objLookup.List;

 

foreach(string msg in array)

 

{

 

    this.lbResult.Items.Add(msg);

 

}

 

txtPath为一个文本框控件,lbResult为一个列表框控件,到此我们就可以察看我们的自定义属性了,这样管理起你自己的代码是不是方便多了,这样你就不用打开程序,只需要把程序集给它,你就可以知道哪一个函数的更新时间,或者是谁写的,其实属性的用途非常的广,具体的就要看你的思路了。

 

    最后我要说的是,我是看了《C#高级编程》后写出来的,所以有很多代码是借鉴这本书的,所以如果你有什么疑惑的话,你可以看一下这本很不错的书。

 


学习中请遵守法律法规,本网站内容均来自于互联网,本网站不负担法律责任
定制 自己 属性
#1楼
发帖时间:2016-7-9   |   查看数:0   |   回复数:0
游客组
快速回复