C#的反射和特性
参考书籍: 《C#图解教程》
Unity 特性可参考: Unity 特性(Attribute)总览
Serializable序列化特性:Unity 序列化(Serialize)介绍、用途
反射是比较神奇的东西,可以找到比较内部东西(类型名,方法名等等)。
自定义特性定义时,名称后面最好加上“Attribute”后缀,而在使用的时候,可以省略后缀“Attribute”,这个C#会自动判断的。
System.Type类
常用:
Type.GetType(String, Boolean, Boolean);
获取String名的类型,是否区分大小写,是否抛异常。
特性
可用于的目标有十个。
- event (事件)
- method (方法)
- property (属性)
- type (类型)
- assemby (程序集)
- field (字段)
- param (参数)
- return (返回值)
- typevar (泛型类参数)
- module (模块)
Obolete
这个经常就出现在一些方法里面,表明方法已经过时了。这个在编译器里面如果写了过时方法,他会提示并给出新方法之类的。
Conditional
System.Diagnostics 命名空间下。
尽量使用这个特性代替#if 、#endif等预处理指令。原因见上一篇。
这个要配合#define用,如下代码:
#define DoTrace
...
[Conditional("DoTrace")] //判断是否有,有就执行下面的方法。
static void TraceMessage() { }
[Conditional("Debug")] //调试模式下执行该函数。
static void checkSomething() { }
CallerFilePath、CallerLineNumber和CallerMemberName
只能用于方法的可选参数(就是默认参数)。分别是调用者的文件路径、代码行数、调用者名。
DebuggerStepThrough
做单步调试时,遇到带这个特性的就直接跳过。可以用于类、结构、构造方法、方法、访问器。
Serializable & NonSerialzed
Serializable 和 NonSerialzed分别是,序列化和反序列化,可以用于跨平台。只能用于类,结构和枚举。就是把序列化的东西翻译成比较底层的语言,而基于这个底层语言可以翻译成多种上一层的语言。
在Unity中,对于两个特性,主要用来显示类在面板中,和隐藏成员变量。
Flags
位标志。用于枚举类型,不改变计算结果,枚举本身就可以作为标记,只是添加Flags提供ToString方法返回成员变量字符串名称集合。
//默认int类型,作控制位不需要负数,可以指定类型为uint,注释为另一种使用位运算的方法。
[Flags]
enum State : uint
{
None = 0x00, // 使用Flags特性,应该要确保0是有效项。
Idle = 0x01, // 1 << 0
Walk = 0x02, // 1 << 1
Run = 0x04, // 1 << 2
Jump = 0x08, // 1 << 3
Attack = 0x10, // 1 << 4
Defense = 0x20 // 1 << 5
}
public class MyClass
{
static void Main()
{
State state;
state = State.Attack | State.Jump; //结果为24(0x18)
Console.WriteLine(state);
Console.ReadKey();
}
}
输出结果:Jump, Attack
如果不添加[Flags],输出结果为 24
其他比较重要的.NET的特性
全局特性
用assembly和module目标名称来生成一些有关公司、产品以及版权信息的元数据。
限制特性类的特性
用AttributeUsage特性。就是限制这个特性用于什么地方。
访问特性
就是反射出特性。
IsDefined
判断是否有用到特性。
GetCustomAttributes
返回用了特性的对象数组。