事件实际上就是一种委托,根据使用的委托类型的不同可以使用自定义委托类型事件,也可以使用预定义委托类型事件
Public delegate void EventHandler(Object sneder,EventArgs e);
是预定义委托EventHandler的委托签名
Sender负责保存触发事件的对象的引用,e负责保存事件数据
使用格式:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace EventTest
{
class Program
{
static void Main(string[] args)
{
EventSample eventSample = new EventSample();
Printer printer = new Printer(eventSample);
eventSample.OnPrintComplete();
Console.WriteLine("remove sendMsg()");
printer.Remove(eventSample);
eventSample.OnPrintComplete();
}
}
public class EventSample
{
public event EventHandler PrintComplete;
public void OnPrintComplete()
{
if(PrintComplete!=null)
{
PrintComplete(this,new EventArgs());
}
}
}
public class Printer
{
public Printer(EventSample eventSample)
{
eventSample.PrintComplete += ShowMessage;
eventSample.PrintComplete += SendMsg;
}
public void ShowMessage(Object sender,EventArgs e)
{
Console.WriteLine("complete print...");
}
public void SendMsg(Object sender,EventArgs e)
{
Console.WriteLine("sendMsg finish");
}
public void Remove(EventSample eventSample)
{
eventSample.PrintComplete -= SendMsg;
}
}
}
使用自定义委托类型的事件:使用与定义的委托时EventArgs参数是不能保存任何事件参数的,如果想传达事件参数,事件处理程序获得事件发布者传达的参数必须使用自定义委托类型的事件才能捕获事件发布者传递给事件处理方法的参数,使用格式如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CustomerDelegateTest
{
public class Program
{
static void Main(string[] args)
{
EventSample eventSample = new EventSample();
Printer printer = new Printer(eventSample);
eventSample.OnPrintComplete();
Console.WriteLine("delete SendMsg");
printer.Remove(eventSample);
eventSample.OnPrintComplete();
}
}
public delegate void PrintEventDelegate(Object sender,PrintEventArgs e);
public class EventSample
{
public event PrintEventDelegate PrintComplete;
public void OnPrintComplete()
{
if (PrintComplete != null)
{
PrintComplete(this, new PrintEventArgs("test data"));
}
}
}
public class PrintEventArgs:EventArgs
{
public string PrintState
{
get;
set;
}
public PrintEventArgs(string state)
{
PrintState = state;
}
}
public class Printer
{
public Printer(EventSample eventSample)
{
eventSample.PrintComplete += ShowMsg;
eventSample.PrintComplete += SendMsg;
}
public void ShowMsg(Object sender, PrintEventArgs printEventArgs)
{
Console.WriteLine("finish print....");
Console.WriteLine("print state {0}",printEventArgs.PrintState);
}
public void SendMsg(Object sender, PrintEventArgs printEventArgs)
{
Console.WriteLine("finish send....");
Console.WriteLine("print state {0}",printEventArgs.PrintState);
}
public void Remove(EventSample eventSample)
{
eventSample.PrintComplete -= SendMsg;
}
}
}
对于程序中出现的形式参数的访问控制权限小于函数或对象的访问控制权限时最好是根据提示,修改对应成员的访问控制权限,主要的原因是由internal类型引起的,默认情况的下的控制权限,只对程序集可见。在使用时要主要public的函数调用internal类型的参数时肯定会报错的,应修改对应类的访问控制权限为public就ok。
事件访问器:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace EventAccessor
{
public delegate void EventHanderCustomer();
public class Mycclass
{
private EventHanderCustomer m_Hander = null;
public void FireAEvent()
{
if (m_Hander != null)
{
m_Hander();
}
}
public event EventHanderCustomer AEvent
{
add
{
Console.WriteLine("AEvent.add is call the hashcode of value is{0}",value.GetHashCode());
if (m_Hander != value)
{
m_Hander = value;
}
}
remove
{
Console.WriteLine("AEvent.remove is call the hashcode of value is{0}",value.GetHashCode());
if (m_Hander == value)
{
m_Hander = null;
}
}
}
}
class Program
{
static void Main(string[] args)
{
Mycclass myclass = new Mycclass();
EventHanderCustomer eventHanderDelegate = new EventHanderCustomer(MyEventHander);
eventHanderDelegate += MyEventHander2;
myclass.AEvent += eventHanderDelegate;
myclass.FireAEvent();
myclass.AEvent -= eventHanderDelegate;
myclass.FireAEvent();
Console.ReadKey();
}
public static void MyEventHander()
{
Console.WriteLine("this is event 1");
}
public static void MyEventHander2()
{
Console.WriteLine("this is event 2");
}
}
}
在事件中定义的私有的委托类型的变量添加委托实例时时有+=后面添加 的应该是委托类型的变量而不能添加方法,value的值是传递到事件的私有成员委托中的委托类型的变量,而不是方法名。
事件中的私有委托类型的变量不属于事件中的成员,事件只是操作该委托类型的变量给其,添加或删除方法的引用。最终的触发事件的方法中操作的是委托类型的变量,事件访问器在整个过程中 的作用只是起着一个操作的作用,事件并不包含私有委托类型的变量这一成员。