zoukankan      html  css  js  c++  java
  • 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, 事件访问器

  • 相关阅读:
    当Django模型迁移时,报No migrations to apply 问题时
    django--各个文件的含义
    django--创建项目
    1013. Battle Over Cities (25)
    1011. World Cup Betting (20)
    1009. Product of Polynomials (25)
    1007. Maximum Subsequence Sum (25)
    1006. Sign In and Sign Out (25)
    1008. Elevator (20)
    1004. Counting Leaves (30)
  • 原文地址:https://www.cnblogs.com/blackcatx/p/5939806.html
Copyright © 2011-2022 走看看