事件Event
實作的類似觀察者設計模式,一對多的通知。
相當于c++的函數指針的一個清單。
Event在UI上的事件回調用途很常見,代碼如下:
public class EventManager : MonoBehaviour
{
public delegate void ClickAction();
public static event ClickAction OnClicked;
void OnGUI()
{
if(GUI.Button(new Rect(Screen.width / - , , , ), "Click"))
{
if(OnClicked != null)
OnClicked();
}
}
}
// 收到點選事件随機改變顔色
public class TurnColorScript : MonoBehaviour
{
void OnEnable()
{
EventManager.OnClicked += TurnColor;
}
void OnDisable()
{
EventManager.OnClicked -= TurnColor;
}
void TurnColor()
{
Color col = new Color(Random.value, Random.value, Random.value);
renderer.material.color = col;
}
}
事件和委托的差別
還是上面代碼,如果去掉event關鍵字也工作正常,這就是委托了……
差別在于加了event後隻能用”+= -=“來添加或移除處理回調而”=“不成,如果寫 EventManager.OnClicked = TurnColor;編譯時就會報錯。
這樣在一定程度上保證了event系統在一個事件觸發後感興趣的系統都會得到通知,而不會被一個錯誤的指派把别的已經注冊的處理都覆寫掉。
匿名函數
c#1(版本)時即使要做的事情非常簡單也必須要有一個專門的做這件事情的方法,是以要為這個方法建立一個委托執行個體。
c#2使用匿名方法對此進行了修正。
這樣就可以不用把外部變量(比如類成員)用參數傳給專門的方法(事件處理),可以直接使用這些變量。
static void HandleDemoEvent( object sender, EventArgs e )
{
Console.WriteLine("Handled by HandleDemoEvent");
}
// C# 1 寫法
EventHandler handler;
handler = new EventHandler(HandleDemoEvent);
handler(null, EventArgs.Empty);
// C# 2 簡寫
handler = HandleDemoEvent;
handler(null, EventArgs.Empty);
// C# 2 匿名方法,直接寫回調方法的實作
String str = "Handled anonymously";
handler = delegate( object sender, EventArgs e )
{
// 外部變量
Console.WriteLine( str );
Console.WriteLine("Handled by HandleDemoEvent");
};
handler(null, EventArgs.Empty);
Action
和delegate差不多的功能,下面一個模拟網絡子產品的類,收到消息後走回調。
public class NetworkManager
{
Queue<Action<string>> Callbacks;
public NetworkManager()
{
callbacks = new Queue<Action<string>>( );
}
public void SendMessage( Action<string> callback )
{
Callbacks.Enqueue(callback);
}
public void Run( )
{
string getData = "這是從網絡得到的消息";
Action<string> callback = Callbacks.Dequeue();
callback(getData);
}
}
class Program
{
static void Main( string[] args )
{
NetworkManager networkMgr = new NetworkManager();
networkMgr.SendMessage((string data) =>
{
Callback(data);
});
networkMgr.Run();
Console.ReadLine();
}
static void Callback( string data )
{
Console.WriteLine(data);
}
}