事情的起因是在项目中看到这样的一段代码
[UnitComponent]
public class ActivityComponent
{
......
}
但不清楚这个[UnitComponent]是如何运作的。网上查了一通后发现是C#的特性标签,遂做此笔记。
自定义标签很简单
1、让一个类继承 Attribute,并且命名为 XXXAttribute
public class UnitComponentAttribute: Attribute
{
public UnitComponentAttribute()
{
}
public UnitComponentAttribute(int param)
{
}
}
2、然后将这个类作为特性标签挂到另一个类ActivityComponent上,书写时可省略Attribute后缀(短记法),也可以不省略(长记法)
[UnitComponent] //短记法
public class ActivityComponent
{
......
}
//或
[UnitComponent(1)]
public class ActivityComponent
{
......
}
3、那这样做的意义是什么呢? 实际上步骤2中的代码在功能上相当于
UnitComponentAttribute attribute = new UnitComponentAttribute();
ActivityComponent.attributeList.Add(attribute);
//或
UnitComponentAttribute attribute = new UnitComponentAttribute(1);
ActivityComponent.attributeList.Add(attribute);
但是这一段代码只有在ActivityComponent的customAttributes属性被访问时才会执行,访问该属性可以初始化并获取到该类的特性。
ActivityComponent.GetCustomAttributes(true); //访问所有特性,返回object[]
ActivityComponent.GetCustomAttributes(); //访问所有特性,返回IEnumberable<Attribute>
ActivityComponent.GetCustomAttribute<UnitComponentAttribute>(); //访问单个特性,其他特性不会被初始化
注: new ActivityComponent()创建对象并不会初始化特性。
4、特性不止可以加在类上,也可以方法 和 属性上。
加在方法上的一个实例:
/*
* 在某些场景中,我们希望一些方法即便上被调用类也不要执行,如调试场景,或者客户端和服务端
* 的公用代码但有区别的部分。
* 那么我们可以使用System.Diagnostics.ConditionalAttribute 特性。
* 该特性接受一个string参数,如果该参数指向的宏定义未被定义,则持有该特性的方法不执行。
* (如果一个方法持有多个ConditionalAttribute特性,则需要全部未定义才不执行该方法)
*/
#define MyMethod
//#define YourMethod 不定义YourMethod
using System;
using System.Diagnostics;
namespace MyNamespace
{
public class ActivityComponent
{
[Conditional("MyMethod")]
public static void MethodA()
{
Console.WriteLine("Run MethodA");
}
[Conditional("YourMethod")]
public static void MethodB()
{
Console.WriteLine("Run MethodB");
}
}
class Program
{
static void Main (string[] args)
{
ActivityComponent.MethodA();
ActivityComponent.MethodB(); //因为YourMethod未定义,所以该函数不被执行
}
}
}
//该程序执行结果为
Run MethodA
Process finished with exit code 0.