• C#笔记-委托&事件


    1.1.委托

    可以认为委托是持有一个或多个方法的对象。被执行时会执行他所有“持有” 的方法

    可以把它看一个类型安全的, 面向对象的c++函数指针

    委托和类一样, 是一种用户自定义的类型。而委托持有一个或多个方法。

    delegate void Mydel(int value); // 声明一个委托类型

    #声明一个委托, 看上去和方法声明相似,只是没有实现块。

    #使用该委托类型声明一个委托变量。 

    #创建一个委托的对象,赋值给委托变量。新的委托对象包括指向某个方法的引用,签名(包括ref,out)和返回类型一致。可以增加方法

    #可以像调用方法一样调用委托。包含的每一个方法都会被执行。可以是实例方法也可以是静态方法。

    #调用带返回值的委托。 最后一个方法返回的值就是委托的返回值, 其它方法返回值都会被忽略

    #调用带引用参数的委托时参数值可能会改变。在执行每个方法时的参数值不同

     delegate void PrintFunction();

    class Program

    {

    }

    1.2.委托使用匿名方法

    #声明委托yojgjf作为初始化的表达式。

    #为委托增加事件时在赋值语句的右边

    #除了数组参数,参数列表必须与委托匹配:参数数量,类型及位置, 修饰符

    #可以省略圆括号来简化参数列表,但必须满足2个条件:委托参数列表不包含out参数;不使用参数

    #如果委托声明有params参数,那么匿名方法的参数列表将忽略params 关键字。

    delegate int OtherDel(int InParam);
    static void Main()
    {
    	OtherDel del = delegate(int x)
    	{
    		return x+20;
    	}
    	//...
    }
    
    delegate void SomeDel(int x);
    SomeDel sDel = delegate
    	{
    		Console.WriteLine("......."):
    	};
    

      

    1.3.Lambda表达式

    Lambda表达式简化了匿名方法的语法, 从而避免包含多余的信息, 使用表达式来替代匿名方法。

    #允许我们省略类型参数(隐式类型)。 如果只有一个隐式类型参数,我们可以省略圆括号le3;

    #允许表达式的主体是语句块或表达式

    #有ref , out 参数时必须注明类型(显式类型)

    #如果没有参数,必须使用一组空的圆括号

    简单说就是 用  MyDel le1 = (int x) => {return x +1}; 就可以了。

    2.1 发布者/订阅者模式

    发布类定义了一系列事件 , 其他类可以“注册”, 以便在这些事件发生时发布者可以通知他们。

    这些订阅者类通过向发布者提供一个方法来“注册”以获取通知。当事件发生时。 发布者“触发事件”, 然后执行订阅者提交的所有事件。 

    2.2 事件

    事件就像是专门用于某种特殊用途的简单委托。事件包含了一个私有委托。

    #事件提供了对它的私有控制委托的结构化访问。也就是说, 你无法直接访问委托。

    #事件中可用的操作比委托要少, 对于事件我们只可以添加,删除或调用事件处理程序。只能用“+= , -="

    #事件上被触发时, 它调用委托来依次调用“调用列表”中的方法。

        delegate void Handler(); // 声明委托
        //发布者
        class Incrementer 
        {
            pulbic event Handler CountedADozen; //创建事件并发布
    
            public void DoCount()
            {
                for (int i = 1; i < 100; i++)
                    if (i % 12 == 0 && CountedADozen != null)
                        CountedADozen ();
            }
        }
    
        //订阅者
        class Dozens
        {
            public int DozensCount { get; private set; }
            public Dozens( Incrementer incrementer )
            {
                DozensCount = 0;
                incrementer.CountedADozen += IncrementDozensCount; //订阅事件
            }
    
            void IncrementDozensCount() //声明事件处理程序
            {
                DozensCount++;
            }
    
        }
        class Program 
        {
            static void Main()
            {
                Incrementer incrementer = new Incrementer ();
                Dozens dozensCounter = new Dozens (incrementer);
                incrementer.DoCount ();
                Console.WriteLine ("{0}", dozensCounter.DozensCount);
            }
        }

     2.2.1 

    》 委托类型声明  事件和事件处理程序必须有共同的签名和返回类型,他们通过委托类型进行描述。

    》事件处理程序声明  

    》事件声明 发布者类必须声明一个订况者类可以注册的事件成员, 当声明的事件为public 时, 称为了发布了事件,

    》事件注册

    》触发事件的代码

    -----

    2.2.2

    public static event Handler CountedADozen;
    

    》可以将事件变成静态的

    》事件是类或结构的成员

    2.3 标准事件

    System命名空间声明的委托类型

    public delegate void EventHandler(object sender, EventArgs e);

    EventArgs类声明在System命名空间中,设计为不参传递任何数据,通常会被忽略。如果你希望传递数据,必须声明一个派生自EventArgs的类,使用合适的字段来保存数据。

        class Incrementer
        {
            public event EventHandler CountedADozen; //使用系统定义的EventHandler
            public void DoCOunt()
            {
                for (int i = 1; i < 100; i++)
                    if (i % 12 == 0 && CountedADozen != null)
                        CountedADozen (this, null); //触发事件时使用参数
            }
    
        }
    
    
        class Dozens
        {
            public int DozensCount{get; private set;}
            public Dozens(Incrementer incrementer)
            {
                DozensCount = 0;
                incrementer.CountedADozen += IncrementDozensCount;
            }
    
            void IncrementDozensCount(object source, EventArgs e )
            {
                DozensCount++;
            }
    
        }

    2.4  通过扩展EventArgs 来传递数据

    public class IncrementerEventArgs :EventArgs
    {
        public int IterationCount{ get; set;}
    }
    
      class Incrementer
        {
            public event EventHandler<IncrementerEventArgs> CountedADozen; //使用系统定义的EventHandler
            public void DoCOunt()
            {
               var arg = new IncrementerEventArgs();
                for (int i = 1; i < 100; i++)
                    if (i % 12 == 0 && CountedADozen != null)
                     {
                        arg.IterationCount = i;
                          CountedADozen (this, arg); //触发事件时使用参数
                      }
            }
    
        }
    
    
        class Dozens
        {
            public int DozensCount{get; private set;}
            public Dozens(Incrementer incrementer)
            {
                DozensCount = 0;
                incrementer.CountedADozen += IncrementDozensCount;
            }
    
            void IncrementDozensCount(object source, IncrementerEventArgs e )
            {
                Console.WriteLine("{0}", e.IterationCount);
                DozensCount++;
            }
    
        }                                                 
    

      2.5, 事件访问器

  • 相关阅读:
    PostMan 安装步骤详解
    使用MySQL,运行系统报错Authentication method 'caching_sha2_password' is not supported.
    jmeter安装和环境变量配置
    Svn项目迁移到Git及Visual Studio 中git使用
    SQLServer 2008以上误操作数据库恢复方法
    ABP入门系列之3——创建实体/Code First创建数据表
    ABP入门系列之2——ABP模板项目
    uni-app使用Canvas绘图
    uni-app中picker组件的一个坑
    Nginx用法详解
  • 原文地址:https://www.cnblogs.com/blackcatx/p/5939806.html
Copyright © 2020-2023  润新知