特性是什么?
特性本质是个类
特性是一种允许我们向程序的程序集添加元数据的语言结构
特性的目的是告诉编译器把程序结构的某组元数据嵌入程序集中
它可以放置在几乎所有的声明中(类、变量、函数等等申明)
自定义特性
特性就是一个类,这个类必须继承 Attribute
类的名称以Attribute为后缀,这样能够表示这个类就是一个特性,当使用特性时,可以省略Attribute这个后缀。
public class MyCustomAttribute : Attribute
{
public string info;
public MyCustomAttribute(string info)
{
this.info = info;
}
}
特性的使用
语法:[特性名(参数列表)]
[MyCustom("类可以使用特性")]
public class Test
{
[MyCustom("成员变量可以使用特性")]
public int value;
[MyCustom("成员方法可以使用特性")]
public void TestFun([MyCustom("参数也可以使用特性")] int value)
{
this.value = value;
}
}
通过反射去使用特性
public class Program
{
public void Main()
{
// 通过反射使用特性
Test test = new Test();
Type t = test.GetType();
// 1. 判断是否用了某个特性
// 参数一:特性的类型
// 参数二:代表是否需要判断继承链
if(t.IsDefined(typeof(MyCustomAttribute), false))
{
Debug.Log("该类型应用了MyCustom特性");
}
// 2. 获得Type元数据中的所有特性
object[] array = t.GetCustomAttributes(true);
for(int i = 0; i < array.Length; i++)
{
if (array[i] is MyCustomAttribute)
{
Debug.Log((array[i] as MyCustomAttribute).info);
}
}
}
}
限制自定义特性的使用范围
通过为特性类 加特性 限制其使用范围
// 参数一:AttributeTargets —— 特性能够用在哪些地方
// AttributeTargets.Class | AttributeTargets.Struct 要么应用于Class,要么应用于Struct。不能应用于其他
// 参数二:AllowMultiple —— 是否允许多个特性实例用在同一个目标上
// 参数三:Inherited —— 特性是否能被派生类和重写成员继承
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple =true, Inherited = false)]
public class MyCustom2Attribute : Attribute
{
}
系统自带特性
1. 过时特性
//参数一:调用过时方法时 提示的内容
//参数二:true-使用该方法时会报错 false-使用该方法时直接警告
[Obsolete("这是一个废弃的方法,请使用NewMethod方法", false)]
public void OldMethod()
{
}
2. 调用者信息特性
//CallerFilePath特性:哪个文件调用?
//CallerLineNumber特性:哪一行调用?
//CallerMemberName特性:哪个函数调用?
//需要引用命名空间 using System.Runtime.CompilerServices;
public void SpeakCaller(string str, [CallerFilePath] string fileName = "",
[CallerLineNumber] int line = 0, [CallerMemberName] string target = "")
{
Console.WriteLine(str);
Console.WriteLine(fileName);
Console.WriteLine(line);
Console.WriteLine(target);
}
3. 条件编译特性
#define UNITY6
public class Program
{
[Conditional("UNITY6")]
static void Fun()
{
Console.WriteLine("Fun执行");
}
}
4. 外部dll包函数特性
用来标记非.Net(C#)的函数,表明该函数在一个外部的DLL中定义。
一般用来调用 C或者C++的Dll包写好的方法
需要引用命名空间 using System.Runtime.InteropServices
[DllImport("Test.dll")]
public static extern int Add(int a, int b);
评论区