属性与反射
更新: 5/13/2026 字数: 0 字 时长: 0 分钟
自定义特性
需继承自 System.Attribute。
Ex:
cs
[System.AttributeUsage(System.AttributeTargets.Class |
System.AttributeTargets.Struct)
]
public class AuthorAttribute : System.Attribute
{
private string Name;
public string Version;
public AuthorAttribute(string name)
{
Name = name;
Version = "1.0";
}
}像使用其他特性一样:
cs
// 为命名参数赋值时,可以用 : 替代 = 跳过有默认值的参数
[Author("P. Ackerman", Version = "1.1")]
class SampleClass { // P. Ackerman's code goes here... }
// 等效于
var anonymousAuthorObject = new Author("P. Ackerman")
{
Version = 1.1
};AttributeUsage 具有一个命名参数,可设置特性能否单次使用或多次使用。
Ex:
cs
[System.AttributeUsage(System.AttributeTargets.Class |
System.AttributeTargets.Struct,
AllowMultiple = true) // 对此使用
]
public class AuthorAttribute : System.Attribute
{
string Name;
public string Version;
public AuthorAttribute(string name)
{
Name = name;
// Default value.
Version = "1.0";
}
public string GetName() => Name;
}
// 使用示例:
[Author("P. Ackerman"), Author("R. Koch", Version = "2.0")]
public class ThirdClass
{
// ...
}使用反射访问特性
特性只是元数据,如果不用反射访问,那价值就会很小。
GetCustomAttributes() 方法返回一个对象数组。此方法有许多重载版本,参阅 Attribute。
Ex:
cs
System.Attribute[] attrs = System.Attribute.GetCustomAttributes(typeof(ThirdClass));一个完整示例:
cs
public static class EventBinder
{
// 游戏启动时调用!比如在 GameManager.Awake()
public static void AutoBindAllEvents()
{
// 1. 找到【所有Unity脚本】(MonoBehaviour子类)
var allMonoTypes = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(assembly => assembly.GetTypes())
.Where(type => type.IsSubclassOf(typeof(MonoBehaviour)));
// 2. 遍历每个脚本里的【所有方法】
foreach (var type in allMonoTypes)
{
var methods = type.GetMethods();
foreach (var method in methods)
{
// 3. 检查方法是否贴了 [EventBind] 特性
var attr = method.GetCustomAttributes(typeof(EventBindAttribute), false)
.FirstOrDefault() as EventBindAttribute;
if (attr == null) continue;
// 4. 把方法自动注册到事件中心
// bool 参数:不搜索父类继承链,仅查找当前方法自身的特性
Action action = (Action)Delegate.CreateDelegate(typeof(Action), method);
EventManager.Register(attr.EventId, action);
Debug.Log($"✅ 自动绑定事件:ID={attr.EventId} → 方法={method.Name}");
}
}
}
}