第十一讲 特性

特性必须以Attribute结尾
 
特性: 就是我们自己定义的修饰符,这种修饰符可可以放到被修饰的对象上面 (特性的本质是一个类)
         特性可以在修饰目标上面额外的扩展信息和行为,对修饰目标没有任何影响
 
定义: 自定义一个普特雷,继承Attribute就可以啦
 
问题:  我们给方法和属性写注释,对目标也没有影响,那特性和注释有什么区别
 
注释:是给开发者用的,是对源码的说明,编译是不参与的
特性:是源码的一部分,编译的时候,会放到元数据中,程序运行时我们可以动态得到,并且可以提取到这些信息后做相关的处理
 
vs:编译原理  写c#代码--->便是成exe/dll文件(IL)(这一步编译的是C#的文件,不能被机器识别"是微软的中间语言")---->CLR(JIT)(被C#文件编译成机器码)----->编译成机器码(10101010)
特性的位置是在:   CLR的编译的IL(部分)+元数据
 
特性的作用:  1:)增加标识  2:)注入信息
 
AttributeUSage: 修饰特性的特性,主要说明这个特性在哪里使用
 
特性可以有多个构造方法,.
特性可以添加方法
并且特性可以继承
 
用属性实现一个数据的校验实例
 
特性定义类:
namespace ConsoleApplication15
{
    /// <summary>
    /// 声明一个统一的校验抽象特性
    /// 特性也是一个类, 所有有类的基本特征,可以继承,抽象
    /// </summary>
    public abstract class BasAttribute : Attribute
    {
        public string Msg { get; set; }
        public BasAttribute(string msg)
        {
            this.Msg = msg;
        }
        public abstract bool CheckData(object obj);
    }
    /// <summary>
    /// 标记注释
    /// </summary>
    public class DisAttribute : Attribute
    {
        public string DisName { get; set; }
        /// <summary>
        /// 属性利用构造函数来初始化,传递值,可以有多个构造函数
        /// </summary>
        /// <param name="disName"></param>
        public DisAttribute(string disName)
        {
            this.DisName = disName;
        }
    }
    /// <summary>
    /// 非空特性判断
    /// </summary>
    public class IsNullAttribute : BasAttribute
    {
        public IsNullAttribute(string msg) : base(msg) { }
        public override bool CheckData(object obj)
        {
            return obj != null && obj.ToString().Length > 0;
        }
    }
    /// <summary>
    /// 取值范围判断
    /// </summary>
    public class RangeAttribute:BasAttribute
    {
        public RangeAttribute(string msg) : base(msg) { }
        public int Max { get; set; }
        public int Min { get; set; }
        public RangeAttribute(int min, int max,string msg)
            : base(msg)
        {
            this.Max = max;
            this.Min = min;
        }
        public override bool CheckData(object obj)
        {
            return this.Min < (int)obj && (int)obj < this.Max;
        }
    }
}
 
特性使用类:
namespace ConsoleApplication15
{
    public class StruntModles
    {
        [IsNull("字段不能为空")]
        public string UserName { get; set; }
        [Range(20,50,"数字超过了取值返回")]
        public int Age { get; set; }
        public string DisMsg { get; set; }
    }
}
 
校验特性类:
namespace ConsoleApplication15
{
    public class DataAttributeCheck
    {
        public static RetuenModles Check<T>(T t)
        {
            RetuenModles mode = new RetuenModles();
            //获取传递的数据的 type(里面包含了类的所有信息)
            Type type = t.GetType();
            //获取共有的属性
            PropertyInfo[] propers = type.GetProperties();
            foreach (PropertyInfo prore in propers)
            {
                //找到属性上面的特性
                var attributes = prore.GetCustomAttributes(typeof(BasAttribute), true);
                foreach(var attr in attributes)
                {                  
                    BasAttribute baattr = attr as BasAttribute;
                    if(!baattr.CheckData(prore.GetValue(t,null)))
                    {
                        mode.IsTrue = false;
                        mode.Msg = prore.Name + "属性:" + baattr.Msg;
                        return mode;
                    }
                }
            }
            mode.IsTrue = true;
            mode.Msg = "校验成功";
            return mode;
        }
    }
}
 
 
校验结果返回类:
 
namespace ConsoleApplication15
{
    /// <summary>
    /// 校验返回数据的Mode
    ///
    /// </summary>
   public  class RetuenModles
    {
       public bool IsTrue{get;set;}
       public string Msg { get; set; }
    }
}
 
使用方法:
 
namespace ConsoleApplication15
{
    class Program
    {
        static void Main(string[] args)
        {
            var mode = new StruntModles() { UserName = "zzl", Age = 17, DisMsg = "校验" };
            RetuenModles md = DataAttributeCheck.Check<StruntModles>(mode);
            Console.WriteLine("校验数据是否通过:" +md.IsTrue);
            Console.WriteLine(md.Msg);
            Console.ReadKey();
        }
    }
}
 
 
 
posted @ 2019-04-08 18:13  瀚海行舟  阅读(195)  评论(0编辑  收藏  举报