.NET编程(04)特性

来源:互联网 发布:轩辕剑昆仑镜进阶数据 编辑:程序博客网 时间:2024/06/04 18:16

.NET编程(04)特性
一:特性和注释的区别
注释:除了让人看懂代码写的是什么,对运行没有任何影响
特性:可以影响编译器([Obsolete(“标记过期”)]),可以影响程序的运行([Serializable]//可以序列化和反序列化),特性其实是生成的metadata,可以通过反射来获取和使用特性的数据

二:自定义特性
自定义特性继承自Attribute类,可以修饰类,接口,属性,参数,返回值等

    [Custom]    [Custom()]    [Custom("这里是学生")]    [Custom("这里是学生", Description = "123456")]    [Custom("这里是学生", Remark = "123456")]    [Custom("这里是学生", Description = "123456", Remark = "123456")]    [Custom(Description = "123456", Remark = "123456")]    public class Student    {        [Custom]//修饰构造函数        public Student()        {            Console.WriteLine("345");        }        [Custom]//修饰属性        public int Id { get; set; }        [Custom]//修饰字段        public string Remark;        [Custom]//修饰方法        public void Study(string name)        {            //new Thread(null).Suspend()            Console.WriteLine("123");        }        [Custom]        [return: Custom]//修饰返回值        public string Answer([Custom]string name)//修饰参数        {            return $"This is {name}";        }    }    

AttributeUsage特性为修饰特性类的特性,可以指定特性类的如何使用。
AttributeTargets.All:表示所有元素都能使用
AllowMultiple = false:表示能不能被多重修饰,默认值为false
Inherited = true:表示是否能被继承,默认值是true

 [AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = true)]    public class CustomAttribute : Attribute    {        public CustomAttribute()        {            Console.WriteLine("这里是CustomAttribute");        }        public CustomAttribute(string remark)        {            Console.WriteLine("这里是CustomAttribute带参数");        }        public string Remark { get; set; }        public string Description { get; set; }        public void Show()        {            Console.WriteLine($"This is {this.GetType().Name}");        }    }    public class CustomChildAttribut : CustomAttribute    {    }

三:通过反射使用特性
type.GetCustomAttribute()方法获取特性的实例

        public static void  Manage(Student student )        {            Type type=student.GetType();            if(type.IsDefined(typeof(CustomAttribute),true))//检查当前类的特性是否存在            {                object item=type.GetCustomAttributes(typeof(CustomAttribute),true)[0] as CustomAttribute;                //foreach(var item in type.GetCustomAttributes(typeof(CustomAttribute),true))                {                    CustomAttribute C=item as CustomAttribute;                    C.Show();                    }            }            foreach(var item in type.GetProperties())            {                if(item.IsDefined(typeof(CustomAttribute),true))                {                    object attribute=type.GetCustomAttributes(typeof(CustomAttribute),true)[0];                }            }            foreach(var item in type.GetFields())            {                if(item.IsDefined(typeof(CustomAttribute),true))                {                    object attribute=type.GetCustomAttributes(typeof(CustomAttribute),true)[0];                }            }            foreach(var item in type.GetConstructors())            {                if(item.IsDefined(typeof(CustomAttribute),true))                {                    object attribute=type.GetCustomAttributes(typeof(CustomAttribute),true)[0];                }            }            MethodInfo method = type.GetMethod("Answer");            if (method.IsDefined(typeof(CustomAttribute), true))            {                object attribute = type.GetCustomAttributes(typeof(CustomAttribute), true)[0];            }            foreach (var item in method.GetParameters())            {                if(item.IsDefined(typeof(CustomAttribute),true))                {                    object attribute = type.GetCustomAttributes(typeof(CustomAttribute), true)[0];                }            }            if (method.ReturnParameter.IsDefined(typeof(CustomAttribute), true))            {                method.ReturnParameter.GetCustomAttribute(typeof(CustomAttribute), true);            }        }

四:特性应用实例
例1:定义Remark特性

[AttributeUsage(AttributeTargets.Enum|AttributeTargets.Field)]    public class RematkAttribute:Attribute    {        public  RematkAttribute(string remark)        {            this.Remark = remark;        }        public string Remark { get; private set; }    }

使用扩展方法获取枚举项的标记特性值

 public static class RemarkExtand    {        /// <summary>        /// 扩展方法        /// </summary>        /// <param name="enumValue"></param>        /// <returns></returns>        public static string GetRemark(this Enum enumValue)        {            Type type = enumValue.GetType();            FieldInfo field =type.GetField(enumValue.ToString());            if (field.IsDefined(typeof(RematkAttribute), true))            {                RematkAttribute rematkAttribute = (RematkAttribute)field.GetCustomAttribute(typeof(RematkAttribute));                return rematkAttribute.Remark;            }            else            {               return  enumValue.ToString();            }        }    }

使用特性来标记枚举

  [Rematk("用户状态")]    public enum UserSate    {        //正常        [Rematk("正常")]        Normal=0,        //冻结        [Rematk("冻结")]        Frozen=1,        //删除        [Rematk("删除")]        Deleted=2    }

例2:验证特性
验证long 类型的数据是否在给定的最大值和最小值之间

 public abstract class AbstractValidataAttibute : Attribute    {        public abstract bool Validata(object Ovalue);    }    public class LongValidataAttibute : AbstractValidataAttibute    {        private long _IMin = 0;        private long _IMax = 0;        public LongValidataAttibute(long IMin,long IMax)        {            this._IMax = IMax;            this._IMin = IMin;        }        public override bool Validata(object Ovalue)        {            return this._IMin < (long)Ovalue && (long)Ovalue < this._IMax;        }    }

标记特性

  [LongValidataAttibute(1000,9999999)]  public long QQ { get; set; }

验证方法

 public class DataValidate    {        public static bool Validate<T>(T t)        {            Type type = t.GetType();            bool result = false;            foreach (var prop in type.GetProperties())            {                if (prop.IsDefined(typeof(AbstractValidataAttibute), true))                {                    object item = prop.GetCustomAttributes(typeof(AbstractValidataAttibute), true)[0];                    AbstractValidataAttibute attribute = item as AbstractValidataAttibute;                    if (!attribute.Validata(prop.GetValue(t)))                    {                        result = true;                        break ;                    }                }            }            return result;        }    }

总结:特性是一个类,可以用来标记元素,编译时生成元数据,使用反射可以得到特性实例对象中包含的数据,提供了更丰富的扩展功能
特性可以看在不破坏原类型封装的前提下,增加额外的功能

原创粉丝点击