今天给大家分享一下我最近折腾的`AttributeUsage`,这玩意儿,一开始我也觉得挺玄乎,不知道有啥用。但是捏,最近在项目里头想搞点自定义特性,就不得不啃一啃这块硬骨头了。
我就是直接上手写特性,噼里啪一顿操作,结果发现,怎么这个特性到处都能用?我想限制一下,只让它用在类上,或者只让它用在方法上,这可咋整?
然后我就开始查资料,这才发现,原来有个`AttributeUsage`这么个玩意儿,专门用来控制你的特性能用在哪儿的。说白了,就是给你的特性加个“说明书”,告诉编译器,这特性只能用在哪些地方。
具体来说,`AttributeUsage`这玩意儿是个特性,你得把它加到你的自定义特性类上面。它主要有几个参数可以设置:
`validOn`:这个是最重要的,它是个`AttributeTargets`枚举,用来指定你的特性可以用在哪些程序元素上。比如`*`就表示只能用在类上,`*`就表示只能用在方法上。你还可以用``运算符把多个目标组合起来,比如`* *`就表示既能用在类上,又能用在方法上。一开始我就没注意到这个参数,所以我的特性就到处乱窜。
`AllowMultiple`:这个参数是个bool值,用来指定你的特性能不能在一个程序元素上用多次。默认是`false`,也就是只能用一次。如果你想让你的特性能用多次,就把它设成`true`。我一开始也没搞清楚这个,以为特性默认就能用多次,结果发现报错了,才明白过来。
`Inherited`:这个参数也是个bool值,用来指定你的特性能不能被派生类继承。默认是`true`,也就是能被继承。如果你不想让你的特性被继承,就把它设成`false`。这个参数我用的不多,一般都让它默认继承。
知道了这几个参数,我就开始动手改造我的自定义特性了。
我定义了一个自定义特性,叫做`MyCustomAttribute`:
csharp
using System;
[AttributeUsage(*, AllowMultiple = false, Inherited = true)]
public class MyCustomAttribute : Attribute
public string Description { get; set; }
public MyCustomAttribute(string description)
Description = description;
这里我用了`AttributeUsage`特性,指定了`validOn`为`*`,也就是说,这个特性只能用在类上。`AllowMultiple`设置为`false`,表示一个类上只能用一次这个特性。`Inherited`设置为`true`,表示派生类可以继承这个特性。
然后,我定义了一个类,叫做`MyClass`,并在上面使用了`MyCustomAttribute`特性:
csharp
[MyCustom("这是一个自定义特性")]
public class MyClass
// ...
这样,我就成功地把`MyCustomAttribute`特性应用到了`MyClass`类上。
我尝试把`MyCustomAttribute`特性应用到方法上,看看会发生什么:
csharp
public class MyClass
[MyCustom("这是一个方法上的自定义特性")] // 编译错误!
public void MyMethod()
// ...
果然,编译器报错了,提示说`MyCustomAttribute`特性不能应用到方法上。这说明`AttributeUsage`起作用了!
通过这回实践,我算是彻底搞明白了`AttributeUsage`的用法。这玩意儿虽然看起来不起眼,但是在控制自定义特性的使用范围方面,还是非常有用的。以后再写自定义特性的时候,一定要记得用`AttributeUsage`给它加上“说明书”,这样才能让你的特性更加规范,更加易于维护。