怎么做网站站长,百度建设公司网站,优秀包装设计网站,网站建设用的是什么软件1. 委托 (Delegate)1.1 基本概念委托是C#中的一种类型#xff0c;它允许将方法作为参数传递#xff0c;类似于C/C中的函数指针#xff0c;但类型安全。1.2 委托声明与使用基本语法#xff1a;csharp// 1. 声明委托类型
delegate void MyDelegate(string message);
delegate…1. 委托 (Delegate)1.1 基本概念委托是C#中的一种类型它允许将方法作为参数传递类似于C/C中的函数指针但类型安全。1.2 委托声明与使用基本语法csharp// 1. 声明委托类型 delegate void MyDelegate(string message); delegate int CalculateDelegate(int a, int b); // 2. 使用委托 public class DelegateExample { // 定义与委托匹配的方法 static void DisplayMessage(string msg) { Console.WriteLine($Message: {msg}); } static int Add(int a, int b) a b; static int Multiply(int a, int b) a * b; static void Main() { // 创建委托实例 MyDelegate messageDelegate new MyDelegate(DisplayMessage); // 调用委托 messageDelegate(Hello Delegate!); // 多播委托示例 CalculateDelegate calcDelegate Add; calcDelegate Multiply; // 添加另一个方法 // 调用多播委托会依次调用所有方法但只返回最后一个结果 int result calcDelegate(3, 4); // 返回Multiply的结果12 } }内置委托类型csharp// Action委托无返回值 Actionstring action1 (msg) Console.WriteLine(msg); Actionint, int action2 (x, y) Console.WriteLine(x y); // Func委托有返回值 Funcint, int, int func1 (a, b) a b; Funcstring, int func2 (s) s.Length; // Predicate委托返回bool Predicateint isEven (num) num % 2 0;2. 事件 (Event)2.1 事件概念事件是基于委托的特殊类型提供了发布-订阅模式增强封装性外部只能订阅/取消订阅不能触发。2.2 标准事件模式csharppublic class EventPublisher { // 1. 定义事件委托标准模式使用EventHandlerT public event EventHandlerMyEventArgs MyEvent; // 2. 定义事件参数类 public class MyEventArgs : EventArgs { public string Message { get; set; } public DateTime Time { get; set; } } // 3. 触发事件的方法 protected virtual void OnMyEvent(string message) { MyEvent?.Invoke(this, new MyEventArgs { Message message, Time DateTime.Now }); } public void DoSomething() { // 业务逻辑... OnMyEvent(Something happened!); } } public class EventSubscriber { public void Subscribe(EventPublisher publisher) { // 订阅事件 publisher.MyEvent HandleEvent; } private void HandleEvent(object sender, EventPublisher.MyEventArgs e) { Console.WriteLine($Event received: {e.Message} at {e.Time}); } } // 使用示例 var publisher new EventPublisher(); var subscriber new EventSubscriber(); subscriber.Subscribe(publisher); publisher.DoSomething();2.3 自定义委托事件csharppublic class TemperatureMonitor { // 自定义委托 public delegate void TemperatureChangedHandler(float oldTemp, float newTemp); // 基于自定义委托的事件 public event TemperatureChangedHandler TemperatureChanged; private float _temperature; public float Temperature { get _temperature; set { if (_temperature ! value) { float oldTemp _temperature; _temperature value; TemperatureChanged?.Invoke(oldTemp, _temperature); } } } }3. UnityEvent3.1 UnityEvent特点UnityEvent是UnityEngine.Events命名空间下的类专为Unity编辑器集成设计支持序列化和可视化配置。3.2 基本用法csharpusing UnityEngine; using UnityEngine.Events; public class UnityEventExample : MonoBehaviour { // 1. 声明UnityEvent无参数 [SerializeField] private UnityEvent onStartEvent; // 2. 声明带参数的UnityEvent [System.Serializable] public class StringEvent : UnityEventstring { } [SerializeField] private StringEvent onMessageEvent; // 3. 声明多个参数的UnityEvent [System.Serializable] public class DamageEvent : UnityEventGameObject, float, Vector3 { } [SerializeField] private DamageEvent onDamageTaken; void Start() { // 代码方式添加监听器 onStartEvent.AddListener(OnStartHandler); onMessageEvent.AddListener(OnMessageHandler); // 触发事件 onStartEvent.Invoke(); onMessageEvent.Invoke(Hello from code!); } void OnStartHandler() { Debug.Log(Start event triggered!); } void OnMessageHandler(string message) { Debug.Log($Message: {message}); } // 触发带多个参数的事件 public void TakeDamage(float amount, Vector3 hitPoint) { onDamageTaken.Invoke(gameObject, amount, hitPoint); } void OnDestroy() { // 清理监听器重要避免内存泄漏 onStartEvent.RemoveAllListeners(); onMessageEvent.RemoveAllListeners(); } }3.3 编辑器中的可视化配置在Unity Inspector中UnityEvent会显示可配置的界面点击添加事件条目拖拽GameObject到Object字段选择组件和方法可以设置参数值3.4 实际应用示例csharp// 开关系统示例 public class Switch : MonoBehaviour { public UnityEvent onTurnOn; public UnityEvent onTurnOff; private bool _isOn false; public void Toggle() { _isOn !_isOn; if (_isOn) onTurnOn.Invoke(); else onTurnOff.Invoke(); } } // 使用Switch的门 public class Door : MonoBehaviour { public void Open() { // 开门动画/逻辑 transform.position Vector3.up * 2; Debug.Log(Door opened!); } public void Close() { // 关门动画/逻辑 transform.position - Vector3.up * 2; Debug.Log(Door closed!); } } // 在Unity编辑器中 // 1. 将Switch脚本添加到开关对象 // 2. 将Door脚本添加到门对象 // 3. 在Switch的Inspector中 // - 拖拽门对象到onTurnOn事件 // - 选择Door.Open方法 // - 拖拽门对象到onTurnOff事件 // - 选择Door.Close方法4. 三者的比较与选择特性DelegateEventUnityEvent封装性低外部可调用高外部只能订阅高序列化不支持不支持支持编辑器集成无无可视化配置性能高高较低有额外开销多播支持是是是使用场景纯代码回调代码事件系统Unity编辑器交互5. 最佳实践5.1 内存管理csharppublic class EventManager : MonoBehaviour { private Dictionarystring, UnityEvent eventDictionary; void Start() { eventDictionary new Dictionarystring, UnityEvent(); } public void StartListening(string eventName, UnityAction listener) { if (!eventDictionary.ContainsKey(eventName)) eventDictionary[eventName] new UnityEvent(); eventDictionary[eventName].AddListener(listener); } public void StopListening(string eventName, UnityAction listener) { if (eventDictionary.ContainsKey(eventName)) eventDictionary[eventName].RemoveListener(listener); } public void TriggerEvent(string eventName) { if (eventDictionary.ContainsKey(eventName)) eventDictionary[eventName].Invoke(); } void OnDestroy() { // 清理所有事件 foreach (var unityEvent in eventDictionary.Values) { unityEvent.RemoveAllListeners(); } eventDictionary.Clear(); } }5.2 性能优化建议避免频繁事件触发特别是在Update方法中使用对象池对于频繁创建/销毁的事件参数缓存委托实例避免每次调用都创建新的委托谨慎使用匿名方法可能导致难以调试的内存泄漏5.3 设计模式应用csharp// 观察者模式实现 public interface IObserver { void OnNotify(string eventType, object data); } public class Subject : MonoBehaviour { private ListIObserver observers new ListIObserver(); public void RegisterObserver(IObserver observer) { observers.Add(observer); } public void UnregisterObserver(IObserver observer) { observers.Remove(observer); } protected void NotifyObservers(string eventType, object data null) { foreach (var observer in observers) { observer.OnNotify(eventType, data); } } }总结委托是基础用于方法引用和回调事件基于委托提供更好的封装适合组件间通信UnityEventUnity专用提供编辑器集成适合非程序员配置在Unity开发中使用C#事件处理纯代码逻辑使用UnityEvent处理需要在编辑器中配置的交互两者可以结合使用发挥各自优势