名称: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
欢迎前来指导和讨论