C#学习笔记 特性
来源:互联网 发布:mac os 变英文 编辑:程序博客网 时间:2024/05/22 11:33
特性是一组用方括号包括的代码,可以为代码提供额外的信息。利用反射,可以为特性提供非常强大的功能。
当编译器遇到一个自定义特性时,会首先把Attribute字符串添加到特性名称后面,形成一个新的名称。如果特性 已经以Attribute结尾,则不会再添加字符串。得到该字符串之后,编译器会在可用的命名空间中查找该特性类,如果找不到该类或者找到的类和特性的用法不匹配,就会报告编译错误。
AttributeUsage特性
为了能够使自定义特性类可以使用,需要为其再添加一个系统定义的特性AttributeUsage,该特性定义了自定义特性该如何使用。
AttributeTargets枚举
可以指定自定义特性究竟应用于哪一层代码上。这个值是由AttributeUsage的第一个参数指定,它是AttributeTargets的枚举。AttributeTargets枚举的成员如下:
- All
- Assembly
- Class
- Constructor
- Delegate
- Enum
- GenericParameter
- Interface
- Method
- Module
- Parameter
- Property
- ReturnValue
- Struct
当自定义特性用Assembly或者Module指定的时候,需要应用到其他特性之前,这时候需要在自定义特性前面添加assembly或者module关键字。
[assembly:MyAttribute(Parameters)]...[module:MyAttribute(Parameters)]
也可以指定特性可以应用于多个元素上,这时候需要用|
将多个值组合起来。
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]class MyAttribute : Attribute{}
AllowMultiple参数
AllowMultiple参数也是AttributeUsage的一个参数,指定了特性能否多次作用于同一元素上。这是一个可选的参数。
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)]class MyAttribute : Attribute{}
Inherited参数
Inherited参数指定特性是否可以被派生的类或接口继承。如果该参数指定为true的话,派生类或者重写的方法或属性就可以自动继承该特性。
这也是一个可选的参数。
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, Inherited = true)]class MyAttribute : Attribute{}
自定义特性的参数
必选参数
必选参数会作为自定义特性类的构造函数的参数传递进去,因此要使用的必选参数的个数和顺序需要和构造函数中的参数个数和顺序相同。
可选参数
可选参数会作为自定义特性类的属性传递进去,因此需要自定义特性类中有和可选参数相同名称的属性或字段存在。
使用自定义特性
知道了这些,就可以编写自己的自定义特性了。
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Constructor, AllowMultiple = true, Inherited = true)]class CodeRecordAttribute : Attribute{ private readonly string lastModifiedTime; public CodeRecordAttribute(string LastModifiedTime) { lastModifiedTime = LastModifiedTime; } public string Author { get; set; } public string LastModifiedTime { get { return lastModifiedTime; } }}
再写一个类,应用我们的自定义特性。
[CodeRecord("2015-9-1", Author = "Leo")]class MyIncompleteWork{ [CodeRecord("2015-9-10", Author = "Leo")] public MyIncompleteWork() { } [CodeRecord("2015-9-9")] public void DoSomething() { }}
最后通过反射来查看一下使用的特性。
internal static void AttributeTest() { //实例化一个类 MyIncompleteWork work = new MyIncompleteWork(); //获取它的Type对象 Type t = work.GetType(); //获取类上定义的特性 CodeRecordAttribute classAttribute = Attribute.GetCustomAttribute(t, typeof(CodeRecordAttribute)) as CodeRecordAttribute; //查看类特性 if (classAttribute != null) Console.WriteLine($"最后修改时间:{classAttribute.LastModifiedTime}, 作者:{classAttribute.Author}"); //获取构造函数上的特性 CodeRecordAttribute cntrAttribute = Attribute.GetCustomAttribute(t.GetConstructor(Type.EmptyTypes), typeof(CodeRecordAttribute)) as CodeRecordAttribute; if (cntrAttribute != null) Console.WriteLine($"最后修改时间:{cntrAttribute.LastModifiedTime}, 作者:{cntrAttribute.Author}"); //获取方法上的特性 CodeRecordAttribute methodAttribute = Attribute.GetCustomAttribute(t.GetMethod("DoSomething"), typeof(CodeRecordAttribute)) as CodeRecordAttribute; if (methodAttribute != null) Console.WriteLine($"最后修改时间:{methodAttribute.LastModifiedTime}, 作者:{methodAttribute.Author}"); }}
- C#特性学习笔记
- C#特性学习笔记
- C#学习笔记 特性
- C#与.NET4 高级程序设计-----语言特性 学习笔记
- C# Attribute 特性 学习
- C#学习------特性
- c#特性,互相学习
- Attribute特性学习笔记
- C#学习笔记(三)—–C#高级特性中的委托与事件(上)
- C#学习笔记(三)—–C#高级特性中的委托与事件(中)
- C#学习笔记(三)—–C#高级特性中的委托与事件(下)
- C#学习笔记(三)—–C#高级特性中的委托与事件:关于事件
- C#学习笔记(三)—–C#高级特性:Lambda表达式
- C#学习笔记(三)—–C#高级特性:匿名方法
- C#学习笔记(三)—–C#高级特性:try语句和异常
- C#学习笔记(三)—–C#高级特性:枚举类型和迭代
- C#学习笔记(三)—–C#高级特性:实现迭代器的捷径
- C#学习笔记(三)—–C#高级特性:可空值类型
- canvas.drawRoundRect 四个角线粗
- 我的iOS学习历程 - 自定义视图
- 虚函数、纯虚函数、普通函数的区别
- iOS常用快捷键总结
- 特征选择(一)-维数问题与类内距离
- C#学习笔记 特性
- Hbase Notes
- java线程池学习
- 循环比赛日程表(match)
- poj 2601 公式推导
- Mysql学习篇之---Windows环境下安装(续)
- C++中子类继承父类构造器和析构器的执行顺序
- 特征选择(二)-聚类变换
- 旭说数据结构之栈的小题目