《CLR via C#》基本类型.定制特性

18.定制特性

18.1使用定制特性

特性允许为每一个元数据表记录项定义和应用信息,在最终的元数据中生成附加信息,这种可扩展的元数据信息能在运行时查询,从而动态地改变代码的执行方式(影响运行时的行为)。

C#只允许特性应用于:程序集、模块、类型(类、结构、枚举、接口和委托)、字段、方法(含构造器)、方法参数、方法返回值、属性、事件和泛型类型参数。

特性的后缀为Attribute,能省略不写,编译器会自动加上。部分特性可以不加前缀,但部分特性必须加前缀,举例:

[return: Some] // 这个前缀必须加,后缀可以不加Attribute
[method: SomeAttribute] // 这个前缀可以不加
public int SomeMethod() { return 0; } // 当多个特性应用于同一个目标元素时,特性的顺序无关紧要

特性必须直接或间接从System.Attribute派生。使用特性其实是在调用特性类的构造函数来new特性类的实例。此外,还支持一些特殊语法:允许设置与特性类关联的公共字段或属性,举例:[DllImport("Kernel32", CharSet = CharSet.Auto, SetLastError = true)],而DllImport的定义是:public DllImportAttribute(string dllName);,所以,第一个参数是构造器参数,称为定位参数,如果有定位参数的话,是必须指定的;用于设置字段或属性的参数是命名参数,是可选的。如果特性类的构造器不获取参数,那么圆括号可以省略(比如:[Flags()]和[Flags])。

每个特性可以单独在一个方括号里(比如:[Serializable][Flags]),也可将多个特性以逗号分隔同时放到一个方括号里(比如:[Serializable, Flags]

18.2定义自己的特性类
[AttributeUsage(AttributeTargets.Enum, Inherited = false)]
public class FlagsAttribute : Attribute
{
    public FlagsAttribute() {}
}

非抽象特性至少要包含一个公共构造器,可以是无参的。类不应提供任何公共方法、事件。AttributeUsage特性(AttributeUsage源码)告诉编译器定制特性的合法应用范围,这个例子的定位参数AttributeTargets.Enum指出Flags特性的实例只能用于枚举类型。AttributeUsage有两个可选参数,分别是Inherited和allowMultiple:Inherited默认为true,表示特性在应用于父类时,能同时应用于子类和子类中重写的方法;还有一个可选参数allowMultiple默认为false,表示特性只能向选定的目标元素应用一次。所以,AttributeUsage特性默认为:能应用于所有目标元素、向同一个目标元素只能应用一次、可继承,可根据自定义特性的需求来更改。

18.3特性构造器和字段/属性数据类型
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值