C#8.C#知识点:委托和事件

知识点目录==========>传送门

第一推荐两篇大牛写的寄托和事件的博客,写的一流好!看了就包你看会,想上学的心上人平昔看这两篇就可以,我要好写的是追根究底自己攻读的记录。

讲到了。我就介绍完啦。最终有一点仓促收尾。哈哈。想要学习的同伙可以看我小说援引的几个博客啦。目前见过写的最好的了。我那么些重中之重是上下一心纪录学习下。写下去明白更长远,映像更胜。不切合我们学习。纯属个人笔记。

                    C# 中的委托和事件续

 

寄托是怎么着?

委托是一个类,它定义了一种的档次,使得可以将艺术当作另一个主意的参数来展开传递,那种将艺术动态地赋给参数的做法,可以幸免在先后中大批量利用If-Else(Switch)语句,同时使得程序有所更好的可增加性。

–摘自百度周全。

概括委托和我们通平时见的类是大概的东西。它也是一个序列,一个对象。委托定义类似定义一种办法模板。满意于这些模板的其余方法都得以赋值于委托。并且将以此委托当参数举办传递,进而把艺术当参数传递。

    public delegate void deTest(string name);

那就定义个从未重临值的信托。定义委托必要重点字 delegate,这么些关键字和大家定义的class关键字是一律的,记住是那样定义的就好了,上面部分就和定义方法的宣示是同等的。去掉delegate关键,就是和定义方法一模一样。

若是满足没有重临值,而且参数是string类型的参数的不二法门都满足于那么些委托。都足以赋值绑定给这些委托。如故地点那句话.定义委托就万分声明了一个艺术的沙盘。

接下去就演示下委托怎样行使

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 委托和事件
{
    public delegate void deTest(string name);
    public class Test
    {
        public void SayHello(string name, deTest test)
        {
            test(name);
        }
    }
}

第一看委托是概念在类外面的,表明定义类的地点都足以定义委托,委托和类是同级关系的。

Test类里面有个SayHello方法。那个艺术有三个参数。一个就是string类型的参数,一个是信托项目标参数。委托项目标参数是怎么样看头呢?意思就是将满意委托模板的不二法门,将艺术当作参数传递。因为从没嘱托方法是独自当参数传递的,最后SayHello方法里面调用那一个委托。因为这一个委托参数本身也是措施。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 委托和事件
{

    class Program
    {
        static void Main(string[] args)
        {

            Test t1 = new Test();
            deTest detest = SayHelloByEngilsh;
            t1.SayHello("小明",detest);
        }

        public static void SayHelloByEngilsh(string name)
        {
            Console.WriteLine(string.Format("Hello{0}", name));
        }
    }
}

先是我们有一个SayHelloByEnglish的措施。这一个主意正好知足大家这一个委托模板,无重返值,有一个string类型的参数。Main函数里将那几个艺术赋值于我们定义的寄托。然后将以此委托传递到大家test的SayHello方法里面。

C# 1

其一事例并不符合利用委托,不是一个好的选择委托的情景,在那中间写首若是为着我们探听委托如何创立使用。现在大家在再一次梳理一下。首先大家定义了一个Test类,在类里面有个SayHello方法。那几个主意有五个参数对吧。

一个是string类型,一个是寄托项目。方法面执行那一个委托。因为委托我就是绑定的法子,值就是情势,所以可以让艺术直接调用。接下来是main函数里面确实的调用。将一个满足委托的主意赋值于委托,然后传递给了那么些办法。最后方法内部实施的信托的时候,其实是执行了大家绑定的章程。也就是SayHelloTest。一个信托创设使用的demo就终止了。

小结下委托

委托赋值语发是+

绑定语法是+=

解绑语法是-=

下边来演示下委托的使用场景,现在我们有个须求,有一个热水器,热水器连接着屏幕,和报警器。热水器温度达到80°的时候,屏幕就会体现提醒,报警器就会报警。先用正常艺术达成下。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 委托和事件
{
    public class WaterHeater
    {
        int temperature = 0;
        public void BoilWater()
        {
            for (int i = 0; i < 80; i++)
            {
                temperature++;
            }
            //报警器报警
            //显示器报警
        }
    }
}

那里就定义个热水器类,这些类就是一个烧水的类。类里面温度平素再加,到了80就开首报警了。报警的操作占时没写。下边就开定义报警类。和出示器类。

    public class Monitor
    {
        public void ShowMessage(int temperature)
        {
            Console.WriteLine(string.Format("热水器在的温度已经{0}°啦,赶紧去洗澡吧", temperature));
        }
    }
    public class Alarm
    {
        public void Police(int temperature)
        {
            Console.WriteLine(string.Format("热水器在的温度已经{0}°啦,赶紧去洗澡吧", temperature));
        }
    }

C#,其一就是显示屏类和烧水类。多个类的事物一样,只有一个简约的报警格局。接下来就是将热水器到了80°之后的报警操作补全。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 委托和事件
{
    public class WaterHeater
    {
        int temperature = 0;
        public void BoilWater()
        {
            for (int i = 0; i < 80; i++)
            {
                temperature++;
            }
            //报警器报警
            Monitor monitor = new Monitor();
            Alarm alarm = new Alarm();
            monitor.ShowMessage(temperature);
            alarm.Police(temperature);//显示器报警

  } }
}

那地点就是new了报警器和屏幕的靶子。然后调用三个对象的告警情势。功用已经落到实处了。可是这些地点有标题。写的很low,看到四个new大家就相应知道那个地点又是强耦合。不便宜须要变动。万一几时我们新加了一个其他报警装置。我还们还要修改那些热水器烧水的点子。设计的很不佳。我们想想那么些地方只是是要在温度到了80°之后执行显示屏和报警器里面的告警格局。我们正好讲过的寄托就是足以和情势绑定。这那些地点大家可以依旧不可以让热水器揭露一个信托变量,热水器温度达到80°之后。调用那个委托变量。委托的绑定放在外边。那样的话。就将高耦合变成了没有耦合,或者说是低耦合。如果没有明白的话。看一手代码。

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 委托和事件
{
  //定义委托
    public delegate void Prompt(int temperature);
    public class WaterHeater
    {
    //声明委托变量
        public Prompt promt;
        public int temperature = 0;
        public void BoilWater()
        {
            for (int i = 0; i < 80; i++)
            {
                temperature++;
            }

            promt(temperature);
        }
    }
}

其一地点大家定义了一个寄托,修改沃特erHeater类表明了一个这一个委托的变量。那些地点我改为调用那几个委托变量用来替代原来的与报警器和显示屏的关联,将事先的高耦合进行解耦。现在那么些类已经和报警器没有一点关乎。不过不可以没有一点涉嫌的对啊。不然怎么调用是吗。接下演示绑定的地点。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 委托和事件
{

    class Program
    {
        static void Main(string[] args)
        {
            Monitor monitor = new Monitor();
            Alarm alarm = new Alarm();
            WaterHeater waterHeater = new WaterHeater();
            waterHeater.promt = monitor.ShowMessage;//委托绑定
            waterHeater.promt += alarm.Police;//委托绑定
            waterHeater.BoilWater();
        }

    }
}

咱俩在main方法里面进行对信托的绑定。大家将事先在类的中间的强耦合提到了外面。假使不需求某个报警装置了,或者大家要加上某个装置。只要在main方法对信托进行绑定,或者解绑就好了。不必要再去修改热水器烧水的代码了。到此地委托的为主接纳就介绍完了,下边介绍下事件。

事件是什么?
事件就是对信托的包裹。举个例子,属性封装了字段。事件就是相当于对信托的包装。有了轩然大波本身赋值可以直接选拔+=或者-=而不要求用+。

上面演示一波事件代码。将事先的代码实行改动。

namespace 委托和事件
{
    public delegate void Prompt(int temperature);
    public class WaterHeater
    {
        private Prompt promt;
        public event Prompt OnPromptEvent;//定义Prompt委托类型的事件。
        public int temperature = 0;
        public void BoilWater()
        {
            for (int i = 0; i < 80; i++)
            {
                temperature++;
            }
        //调用事件
            OnPromptEvent(temperature);
        }
    }

那些地点我们又声称了一个事变。并且将调用委托的地方改为了事件,还将委托的访问类型改为私有。main方法咱们也进展了改动。

事件小统计

1.扬言关键字 event

2.关键字前边紧跟委托项目

修改main方法

        static void Main(string[] args)
        {
            Monitor monitor = new Monitor();
            Alarm alarm = new Alarm();
            WaterHeater waterHeater = new WaterHeater();
            waterHeater.OnPromptEvent += monitor.ShowMessage;
            waterHeater.OnPromptEvent += alarm.Police;
            waterHeater.BoilWater();
        }

将委托的绑定改为了事件绑定。到了那里有没有同桌发现和大家winform
按钮事件是极为相似的,其实按钮这些点击事件也是其一事件。

   this.button1.Click += new System.EventHandler(this.button1_Click);


   private void button1_Click(object sender, EventArgs e)
   {

   }

那是Vs帮大家转移的按钮绑定事件,是否和我们写的相同。然则仔细的娃儿可能会说:参数定义不平等,Vs里面的事件都会有(object
sender, 伊夫ntArgs e)那三个参数。

实际上那是微软概念的一种委托事件注解的正式。sender
传递触发者,伊芙ntArgs参数传递而外信息。比如大家写的不行demo sender就是热水器本身,参数大家就要传递的热度。上面我来修改一下。

第一添加一个参数类继承于伊夫ntArgs我们自定义的要传送的参数都无冕于伊夫ntArgs。篇幅有限定,不详细介绍。可以友善查阅资料仍然看自己小说看透推荐的博客。

 

    public class BoiledEventArgs : EventArgs
    {
        public readonly int temperature;
        public BoiledEventArgs(int temperature)
        {
            this.temperature = temperature;
        }
    }

修改了体现器类和报警器类的章程签名

    public class Monitor
    {
        public void ShowMessage(object sender, BoiledEventArgs e)
        {
            Console.WriteLine(string.Format("热水器在的温度已经{0}°啦,赶紧去洗澡吧", e.temperature));
        }
    }
    public class Alarm
    {
        public void Police(object sender, BoiledEventArgs e)
        {
            Console.WriteLine(string.Format("热水器在的温度已经{0}°啦,赶紧去洗澡吧", e.temperature));
        }
    }

修改热水器类

    public delegate void Prompt(object sender, BoiledEventArgs e);
    public class WaterHeater
    {
        private Prompt promt;

        //定义Prompt类型事件
        public event Prompt OnPromptEvent;
        public int temperature = 0;
        public void BoilWater()
        {
            for (int i = 0; i < 80; i++)
            {
                temperature++;
            }
            BoiledEventArgs e = new BoiledEventArgs(temperature);
            OnPromptEvent(this, e);
        }
    }

main方法是不用动的。

总体代码:

C# 2C# 3

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 委托和事件
{
    public delegate void Prompt(object sender, BoiledEventArgs e);
    public class WaterHeater
    {
        private Prompt promt;

        //定义Prompt类型事件
        public event Prompt OnPromptEvent;
        public int temperature = 0;
        public void BoilWater()
        {
            for (int i = 0; i < 80; i++)
            {
                temperature++;
            }
            BoiledEventArgs e = new BoiledEventArgs(temperature);
            OnPromptEvent(this, e);
        }
    }

    // 定义BoiledEventArgs类,传递需要的的信息
    public class BoiledEventArgs : EventArgs
    {
        public readonly int temperature;
        public BoiledEventArgs(int temperature)
        {
            this.temperature = temperature;
        }
    }


    public class Monitor
    {
        public void ShowMessage(object sender, BoiledEventArgs e)
        {
            Console.WriteLine(string.Format("热水器在的温度已经{0}°啦,赶紧去洗澡吧", e.temperature));
        }
    }
    public class Alarm
    {
        public void Police(object sender, BoiledEventArgs e)
        {
            Console.WriteLine(string.Format("热水器在的温度已经{0}°啦,赶紧去洗澡吧", e.temperature));
        }
    }
}

View Code

    传送门==========》C# 中的委托和事件

相关文章