c#-Attribute特性认知

名称:Attribute / 特性  

关键理解:特性声明是没有作用的,只用用反射查找的时候特性才会有作用(也就是说特性必须要结合反射来用,MVC等一些框架支持了特性的反射调用)

特性的本质:特性是一个类,可以用来标记元素。编译时生成到 Matadata 里面,平时不影响程序的运行,除非主动用反射去查找

功能:特性可以在不破坏类型封装的前提下,额外的增加功能

AOP:面向切面的时候用到(对OOP的补充)

在c#程序给我们封装了很多特性 在MVC /WebService/WCF等都用到了特性

 

下面我们自己写一个特性:

 这个特性的使用方式:获取枚举的实际值的时候我们还能额外的获取中文意思

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Reflection;
 5 using System.Text;
 6 using System.Threading.Tasks;
 7 
 8 namespace AttributeStudy.Atrributes
 9 {
10     /// <summary>
11     /// AttributeUsage 给特性设定权限的(第一个参数约定了特性使用的范围,第二个约定了是否可以多次约定默认是false,第三个自约定是否子类继承后是否继承父类特性,默认是true)
12     /// </summary>
13     [AttributeUsage(AttributeTargets.Enum | AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
14     public class RemarkAttribute : Attribute //特性实际就是一个类,继承了Attribute
15     {
16         /// <summary>
17         /// 特性就是一个类,也就是特性也有字段/属性/方法等
18         /// </summary>
19         public string Remark; 
20 
21         public RemarkAttribute(string remark)
22         {
23             this.Remark = remark;
24         }
25     }
26 
27     public static class RemarkEx
28     {
29         /// <summary>
30         /// 反射调用特性
31         /// </summary>
32         /// <param name="enumValue"></param>
33         /// <returns></returns>
34         public static string GetRemark(this Enum enumValue)
35         {
36             Type type = enumValue.GetType();                       //反射获取类型
37             FieldInfo field = type.GetField(enumValue.ToString()); //通过名称获取字段
38 
39             if (field.IsDefined(typeof(RemarkAttribute), true))    //通过IsDefined方法查找该字段上面是否有RemarkAttribute特性
40             {
41                 RemarkAttribute remarkAttribute = (RemarkAttribute)field.GetCustomAttribute(typeof(RemarkAttribute));//通过类型查找到特性然后得到实例
42                 return remarkAttribute.Remark;                     //调用特性的方法
43             }
44             else
45             {
46                 return enumValue.ToString();
47             }
48         }
49     }
50 
51 
52     /// <summary>
53     /// 使用特性的枚举
54     /// </summary>
55     [Remark("用户权限")]
56     public enum USERCLASS
57     {
58         [Remark("最炫的名族风")]
59         Nomarl = 1,
60         [Remark("尊贵")]
61         IsTrue = 2,
62         [Remark("VIP")]
63         IsFlade = 3
64     }
65 }

另一个自定义特性,自定义一个类 声明long类型的字段 在long类型的字段上使用特性

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace AttributeStudy.Atrributes
 8 {
 9     /// <summary>
10     /// 该特性是判断long类型的字段的值是否在指定的范围
11     /// 1.定义一个虚特性 AbstractValidataAttribute 作为base类 提供继承扩展
12     /// </summary>
13     public abstract class AbstractValidataAttribute : Attribute
14     {
15         public abstract bool Validata(object oValue);
16     }
17 
18     public class longValidataAttribute : AbstractValidataAttribute //2.定义longValidataAttribute 类继承实现基类
19     {
20         private long _lMin; //最小范围
21         private long _lMax; //最大范围
22 
23         public longValidataAttribute(long lMin, long lMax)
24         {
25             _lMax = lMax;
26             _lMin = lMin;
27         }
28 
29         public override bool Validata(object oValue) //重写实现基类方法,该方法检查传入的参数是否在规定的范围
30         {
31             return this._lMin < (long)oValue && (long)oValue < this._lMax;
32         }
33     }
34 
35     public class RequredValidataAttribute : AbstractValidataAttribute
36     {
37         public override bool Validata(object oValue)
38         {
39             if (string.IsNullOrEmpty((string)oValue))
40             {
41                 return false;
42             }
43             else
44             {
45                 return true;
46             }
47         }
48     }
49 
50     public class DataValidata
51     {
52         public bool Validata<T>(T t)
53         {
54             Type type = t.GetType();
55             bool Result = true;
56             foreach (var prop in type.GetProperties()) //获取当前类的所有的公共属性,并循环
57             {
58                 if (prop.IsDefined(typeof(AbstractValidataAttribute), true)) //查找属性上面是否有特性
59                 {
60                     object oProp = prop.GetCustomAttributes(typeof(AbstractValidataAttribute), true)[0];//获取特性的实例
61                     AbstractValidataAttribute abstractValidataAttribute = oProp as AbstractValidataAttribute;
62                     if (!abstractValidataAttribute.Validata(prop.GetValue(t))) //调用特性的方法传入字段的值检查 .GetValue()获取值
63                     {
64                         Result = false;
65                         break;
66                     }
67                 }
68             }
69             return Result;
70         }
71     }
72 
73 }

以上就是我对特性的理解,有什么疑问加我的QQ:443069755

欢迎前来指导和讨论

 

posted @ 2018-03-25 23:07  Torylon  阅读(214)  评论(0编辑  收藏  举报