前言:有时我们需要手动的绑定事件比如按钮的在Start中 AddListener和 在OnDisable中 RemoveListener等,设计一个自动化的场景。
- 自动绑定事件特性
- AutoSub(自动绑定事件特性)
- (事件类型)EventType
- EventType(枚举函数)
- BaseLayer(Demo类)
- Dictionary<int, Action<object, object[]>> records(维护变量)
- AutoListenEvents(自动绑定函数)
- RemoveEvents(取消绑定)
- Layer1:BaseLayer(测试类)
- Events(测试函数)
- Trigger(触发类)
- AutoSub(自动绑定事件特性)
1:特性枚举类
//标记类
[Preserve]//防止被优化掉
public class AutoSub : PreserveAttribute
{
public EventType Type;
//Message....
public AutoSub(EventType eventType)
{
Type = eventType;
}
}
//事件枚举类
public enum EventType
{
Type1 = 1,
Type2 = 2,
}
2:测试基类
public class BaseLayer : MonoBehaviour
{
public Dictionary<int, Action<object, object[]>> records;
// Start is called before the first frame update
protected virtual void Start()
{
//Sub..
AutoListenEvents(GetType(), this);
}
private void OnDestroy()
{
//UnSub..
RemoveEvents();
}
//自动绑定函数
private void AutoListenEvents(Type typeDefinition, BaseLayer layer)
{
records = new Dictionary<int, Action<object, object[]>>();
var methods = typeDefinition.GetRuntimeMethods();
foreach (var method in methods)
{
if (method.IsConstructor || method.IsStatic) continue;
var attribute = method.GetCustomAttribute<AutoSub>();
if (attribute != null)
{
if (!records.ContainsKey((int)attribute.Type))
{
//MethodInfo转Action
Action<object, object[]> action =
(Action<object, object[]>)method.CreateDelegate(typeof(Action<object, object[]>), this);
records.Add((int)attribute.Type, action);
}
}
}
}
private void RemoveEvents()
{
records.Clear();
}
}
3:测试子类
public class Layer1 : BaseLayer
{
//测试函数
public void Trigger()
{
foreach (KeyValuePair<int, Action<object, object[]>> pair in records)
{
if (pair.Key == 1)
{
//XXX.Fire(...)
pair.Value?.Invoke(1, new object[] { 2, 3 });
}
}
}
//实际用例
[AutoSub(EventType.Type1)]
public void Events(object arg1, object[] arg2)//参数等等....
{
Debug.Log(arg1);
foreach (object o in arg2)
{
Debug.Log(o);
}
}
}
4:结果
5:参考文献
c# - How can I create an Action delegate from MethodInfo? - Stack Overflow