委托与事件机制小总结

最近因为工作需要等等原因要开始写.Net code 所以先来学习过一遍C#,感觉还好 ,大学就学习过java感觉差不多吧,但是要对于特殊的机制与特性要重点学习,这就是C#的事件以及委托(关乎到写回到函数的实现)

委托机制:
委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递。事件是一种特殊的委托。
委托的作用:c#中的委托也是为了回调!

四种委托:Delegate,Action ,Func,predicate
Delegate定义:

public delegate int MethodtDelegate(int x, int y);表示有两个参数,并返回int型。

Action定义:

public void Test<T>(Action<T> action,T p)
        {
            action(p);
        }

Action 是无返回值的泛型委托;Action 表示无参,无返回值的委托, Action 至少 0 个参数,至多 16 个参数,无返回值。

Func定义:

public int Test<T1,T2>(Func<T1,T2,int>func,T1 a,T2 b)
        {
            return func(a, b);
        }

Func 是有返回值的泛型委托;Func 表示无参,返回值为 int 的委托;

predicate定义:

public delegate bool Predicate<T> (T obj)

委托特点:

  • 委托类似于 C++ 函数指针,但它们是类型安全的。
  • 委托允许将方法作为参数进行传递。
  • 委托可用于定义回调方法。
  • 委托可以链接在一起;例如,可以对一个事件调用多个方法。 方法不必与委托签名完全匹配。

总结一下:

  1. Delegate 至少 0 个参数,至多 32 个参数,可以无返回值,也可以指定返回值类型
  2. Func 可以接受 0 个至 16 个传入参数,必须具有返回值
  3. Action 可以接受 0 个至 16 个传入参数,无返回值
  4. Predicate 只能接受一个传入参数,返回值为 bool 类型

事件机制:
事件涉及两类角色-事件发布者和事件订阅者。当发生一个事件的时候,事件发布者会发布事件,事件订阅者会接收事件已发生的通知,并且做出相应的处理。其中,触发事件的对象称之为事件发布者,捕获事件并且对其做出处理的称之为事件订阅者。

定义事件:
访问修饰符 event 委托类型 事件名

public event EventHandler birthday

事件订阅者需要订阅事件发布者发布的事件,以便在事件被触发时接收消息并且做出处理。我们可以使用+=来订阅事件,使用-=来
取消订阅事件。
EventHandler只用来处理不包含事件处理的事件。如果我们想在这种方式定义的事件中包含事件数据(传参数或者数据等等),则可以通过派生EventArgs来实现。

如何使用事件:

//第1步,申明一个委托 
public delegate int SomeDelegate(string s, bool b);
 //第2步,定义符合委托签名(即参数个数与类型一致)的函数。 
private int SomeFunction(string s, bool b){...} 
//--前2步都相同 
//第3步,申明一个的事件,并定义该事件能接受的签名。 
public event SomeDelegate SomethingHappened; 
//第4步,通过事件来保存符合签名的函数(可以是多个) 
myObj.SomethingHappened += new SomeDelegate(SomeFunction); 
//第5步,根据需要在适当的时机,运行事件中保存的函数 
if( SomethingHappened != null ) { 
foreach( SomeDelegate sd in SomethingHappened.GetInvocationList() ) { 
int result = sd("somestring", true); 
    } 
}

委托与事件的区别:
(1)C#中事件:事件时属于类的成员,所以要放在类的内部。
(2)委托属于一个定义,是和类、接口类似的,通常放在外部。
(因为大多数委托都要被重用)
委托定义在类里面还是类外面视情况而定,一般定义在与类定义平级部分,且用public修饰,便于外部调用。
若定义在类的内部,则必须通过调用该类的成员才能取得其委托的引用,频繁调用的情况下不合适。

委托与事件的联系:
从事件的声明,我们可以大致看出事件与委托的关系,事件是委托的特殊实现,事件是建立在对委托的语言支持之上的。
委托是一种类型,事件是委托类型的一个实例,加上了event的权限控制,限制权限,只允许在事件声明类里面去invoke和赋值,不允许外面,甚至子类调用。

Delegate.Invoke、Delegate.BeginInvoke And Control.Invoke、Control.BeginInvoke区别
其中Invoke是同步,而BeginInvoke异步

1、Delegate.Invoke (委托同步调用)
  a、委托的Invoke方法,在当前线程中执行委托。
  b、委托执行时阻塞当前线程,直到委托执行完毕,当前线程才继续向下执行。
  c、委托的Invoke方法,类似方法的常规调用。
2、Delegate.BeginInvoke (委托异步调用)
  a、委托的BeginInvoke方法,在线程池分配的子线程中执行委托。
  b、委托执行时不会阻塞主线程(调用委托的BeginInvoke线程),主线程继续向下执行,毕竟是异步。
  c、委托执行时会阻塞子线程。
  d、委托结束时,如果有返回值,子线程讲返回值传递给主线程;如果有回调函数,子线程将继续执行回调函数。
1、Control.Invoke (同步调用)  
  (1)在主线程(UI线程)中调用Control.Invoke
    a、在主线程(UI线程)中调用Control.Invoke,先执行Invoke的方法,再执行Invoke后面的代码。
  (2)在子线程中调用Control.Invoke
    a、子线程中调用Control.Invoke,子线程将调用的方法封装成消息,调用API的RegisterWindowMessage()向UI窗口发送消息。 主线程继续向下执行,子线程处于阻塞状态。
    b、当该消息被主线程执行完成后,子线程才能继续往下执行。
2、Control.BeginInvoke (异步调用)
  (1)在主线程(UI线程)中调用Control.BeginInvoke
    a、在主线程(UI线程)中调用Control.BeginInvoke,将调用的方法封装成消息,调用API的RegisterWindowMessage()向UI窗口发送消息。先执行Invoke后面的代码,再执行Invoke的方法。
  (2)在子线程中调用Control.BeginInvoke
    a、子线程中调用Control.BeginInvoke,子线程将调用的方法封装成消息,调用API的RegisterWindowMessage()向UI窗口发送消息。主线程继续向下执行,子线程也继续向下执行。
    b、最后由主线程执行Invoke的方法。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值