.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; } }
总结:特性是一个类,可以用来标记元素,编译时生成元数据,使用反射可以得到特性实例对象中包含的数据,提供了更丰富的扩展功能
特性可以看在不破坏原类型封装的前提下,增加额外的功能
阅读全文
0 0
- .NET编程(04)特性
- NET特性编程(Attribute)
- .net 4.0新特性-并行编程(转)
- .Net 特性(Attribute)
- .NET特性(attribute)总结
- .Net的特性(attribute)....
- .NET内置特性(一)
- .net特性
- .net Framework拾遗(2) 特性Attribute
- .Net一些基本语言特性(一)
- VB.NET特性---- Dllimport特性
- VB.NET特性---- Dllimport特性
- VB.NET特性---- Dllimport特性
- VB.NET特性---- Dllimport特性
- VB.NET特性---- Dllimport特性
- (16)反射、特性和动态编程
- grails-数据库编程(高级GORM特性)
- PL/SQL编程(高级特性)
- 第十周 数据结构例程——二叉树的构造
- 从一个图片读数据,由这个数据来填充新建图片文件
- Bilateral Filter:保护边缘的平滑滤波器
- Linux设备模型(4)_sysfs
- 数据结构上机实践第九周项目1
- .NET编程(04)特性
- svn 简单命令
- 双系统windows+linux如何正确删除linux
- 第八周(2) 项目3.2-稀疏矩阵的三元组表示的实现及应用
- Ubuntu15.10版本apt源地址笔记
- jmeter教程
- 《算法图解》第九章 动态规划
- 多线程交替打印ABC的多种实现方法
- 堆 (heap)