• [C#]简单的理解委托和事件


    委托

    在C++中可以利用“函数指针”将对方法的引用作为实参传递给另一个方法,而C#中可以利用委托提供相同的功能。

    委托-内部机制

    但是委托实际上是一个特殊的类。委托必须直接或间接的派生自System.Delegate。实际的委托类型总是派生自System.MulticastDelegate(创建委托的时候,编译器自动继承的是MulticastDelegate而不是Delegate),后者又从Delegate派生。

    委托内部包含了几个重要的属性:第一个就是System.Reflection.MethodInfo类型的,它描述了特定方法的签名,包括方法名称、参数和返回类型。除了MethodInfo,委托还需要一个对象实例,其中包含了要调用的方法,这是第二个属性Target的作用。(如果是静态方法,则Target对应类型自身)。

    Func和Action

    为了减少自定义委托类型的必要,.NET 3.5包含了一组通用的委托,其中大多数都是泛型。System.Func系列委托代表有返回值的方法,而System.Action表示返回void的方法。

    
    Public delegate void Action();
    
    Public delegate void Action<in T>(T arg)
    
    Public delegate void Action<in T1,in T2>(in T1 arg1,in T2 arg2)
    
    Public delegate void Action<in T1,in T2,in T3>(in T1 arg1,in T2 arg2,in T3 arg3)
    
    …….
    
    Public delegate void Action<in T1,in T2,in T3,in T4,in T5,in T6,in T7,in T8,in T9,in T10,in T11,in T12,in T13,in T14,in T15,in T16>(T1 arg1,T2 arg2,T3 arg3,T4 arg4,T5 arg5,T6 arg6,T7 arg7,T8 arg8,T9 arg9,T10 arg10, T11 arg11,T12 arg12, T13 arg13, T14 arg14,T15 arg15, T16 arg16)
    
    
    
    
    
    Public delegate Tresult Func<out TResult>();
    
    Public delegate Tresult Func<in T,out TResult>(T arg);
    
    Public delegate Tresult Func<in T1,in T2,out TResult>(T1 arg1,T2 arg2);
    
    ……
    
    Public delegate Tresult  Func<in T1,in T2,in T3,in T4,in T5,in T6,in T7,in T8,in T9,in T10,in T11,in T12,in T13,in T14,in T15,out TResult>(T1 arg1,T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6,T7 arg7,T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15,T16 arg16)
    
    

     

    事件

    说到事件,得知道委托的几个缺陷:

    1、在使用+=赋值操作符时使用了=,会导致一个全新的委托链代替了前面链,这是一个十分容易犯的错误,所以event提供了额外的封装,避免不小心取消了其他订阅者。

    2、可以在委托包容类的外部调用委托,这是由于委托的封装不充分。

    3、普通委托还有一个不利之处在于,很容易忘记在调用委托之前检查null值(在C#6中使用 ?.  null条件操作符),这会引发一个异常。

     

    而事件就可以很简单的理解了,就是对委托的进一步封装,解决了委托存在的一些缺陷。

     

    事件-内部机制

    事件限制外部类只能通过+=操作符向发布者添加订阅方法,并用-=操作符取消订阅,除此之外什么都不能做。此外,还禁止除包容类之外的任何其他类调用事件。为了达到上述目的,C#编译器会获取带有event修饰符的public委托变量,并将委托声明为private。此外,它还会添加两个方法和两个特殊的事件块,这里就不展开了。

    https://github.com/li-zheng-hao
  • 相关阅读:
    ecshop 浏览历史样式的修改
    ECSHOP任意页面调用商品属性
    ECShop url路径 商品详情页goods 商品列表页category 修改成你想要的
    ecshop模板增加新lbi库文件注意事项
    最完美带qq昵称qq头像的qq帐号登录ecshop插件
    ECSHOP2.72 前台调用 定单号,及收货人,快递号
    ecshop后台帐号密码忘记了怎么办?
    ECSHOP首页成功实现订单上下滚动
    ECSHOP 注册就送红包
    ECSHOP隐藏帮助中心文章页的评论功能方法
  • 原文地址:https://www.cnblogs.com/lizhenghao126/p/11053664.html
Copyright © 2020-2023  润新知