C#委托和事件

1. 委托

 PlayMusic.cs

using System;
using System.Collections.Generic;

namespace 事件练习
{
    //声明委托
    public delegate void delPlay();
    public class PlayMusic
    {
        //定义委托
        public delPlay delPlaySong;
        public string Name { get; set; }

        public PlayMusic(string name)
        {
            Name = name;
        }
        public void Play()
        {
            Console.WriteLine("Playing the {0}", this.Name);
            //使用委托
            if(delPlaySong != null)
            {
                delPlaySong();
            }
        }
    }
}

Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;

namespace 事件练习
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            PlayMusic pm = new PlayMusic("My");

            //初始化委托
            pm.delPlaySong = Test;
            pm.Play();
        }

        public void Test()
        {
            Console.WriteLine("Test");
        }

    }
}

 

2. 事件

PlayMusic.cs

using System;
using System.Collections.Generic;

namespace 事件练习
{
    //声明委托
    public delegate void delPlay();
    public class PlayMusic
    {
        //定义事件
        public event delPlay delPlaySong;
        public string Name { get; set; }

        public PlayMusic(string name)
        {
            Name = name;
        }
        public void Play()
        {
            Console.WriteLine("Playing the {0}", this.Name);
            //使用委托
            if(delPlaySong != null)
            {
                delPlaySong();
            }
        }
    }
}

Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;

namespace 事件练习
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        //sender:触发事件的对象
        //e: 执行事件所需要的数据资源
        private void button1_Click(object sender, EventArgs e)
        {
            PlayMusic pm = new PlayMusic("My");

            //注册事件 
            pm.delPlaySong += Test;
            pm.Play();
        }

        //EventArgs为MouseEventArgs的父类
        private void button1_MouseDown(object sender, MouseEventArgs e)
        {

        }

        public void Test()
        {
            Console.WriteLine("Test");
        }

    }
}

 3. 直接定义事件

PlayMusic.cs

using System;
using System.Collections.Generic;

namespace 事件练习
{
    //声明委托
    public delegate void delPlay();
    public class PlayMusic
    {
        public delPlay delPlaySong;

        //定义事件,该PlaySong需要两个参数(object sender, EventArgs e)
        public event EventHandler PlaySongEvent;
        public string Name { get; set; }

        public PlayMusic(string name)
        {
            Name = name;
        }
        public void Play()
        {
            Console.WriteLine("Playing the {0}", this.Name);
            //使用事件
            if(PlaySongEvent != null)
            {
                EventArgs e = new EventArgs();
                //定义该事件的类内可以直接调用
                PlaySongEvent(this,e);//执行事件,注意:执行之前要注册事件

            }

            if (delPlaySong != null)
            {
                //直接调用 
                delPlaySong();
            }
            else
                return;
        }
    }
}

Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;

namespace 事件练习
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            PlayMusic pm = new PlayMusic("My");

            //注册要执行的事件,按两下Tab键
            pm.PlaySongEvent += pm_PlaySongEvent;
            //pm.PlaySongEvent();//在其他类中,只能出现在+=或-=之前

             //使用委托 
            pm.delPlaySong = Test;
            pm.delPlaySong();//只要不为空,是可以直接调用的
            //pm.delPlaySong += Test;
            pm.Play();

            //事件是在为了将委托保护起来,因为委托是随处可以调用的。
            //事件却不能被随意调用
            //事件的本质是类型安全的委托
            //事件是多播委托
        }

        void pm_PlaySongEvent(object sender, EventArgs e)
        {
            //throw new NotImplementedException();
            PlayMusic p = sender as PlayMusic;

            Console.WriteLine(p.Name + " Ok");
        }

        public void Test()
        {
            Console.WriteLine("Test");
        }

    }
}

4. 总结

委托作用:占位,在不知道将来要执行的方法的具体代码时,可以先用一个委托变量来代替方法调用(委托的返回值,参数列别确定)。在实际调用之前,需要为委托赋值,否则为null;

事件的作用:与委托变量一样,只是功能上比委托变量有更多的限制,事件内部封装了一个多播委托。

事件的本质是类型安全的委托。

posted @ 2017-12-01 15:09  mCat  Views(213)  Comments(0Edit  收藏  举报