C# 教程 在线

2426C# 事件(Event)

一个事件调用委托的简单例子:

using System;

/*功能:当起床铃声响起,就引发学生起床/厨师做早餐两个事件
*/

// 定义一个委托(也可以定义在Ring类里面)
public delegate void DoSomething();

// 产生事件的类 
public class Ring
{
    // 声明一个委托事件
    public event DoSomething doIt;

    // 构造函数
    public Ring()
    {
    }

    // 定义一个方法,即"响铃"   引发一个事件
    public void RaiseEvent()
    {
        Console.WriteLine("铃声响了.......");

        // 判断事件是否有调用委托(是不是要求叫学生起床,叫厨师做饭)
        if (null != doIt)
        {
            doIt(); //  如果有注册的对象,那就调用委托(叫学生起床,叫厨师做饭)
        }else{
        Console.WriteLine("无事发生......."); //没有注册,事件没有调用任何委托
    }
    }
}

// 学生类( 处理事件类一)
public class HandleEventOfStudents
{
    // 默认构造函数
    public HandleEventOfStudents()
    {
    }

    //叫学生起床
    public void GetUp()
    {
        Console.WriteLine("[学生]:听到起床铃声响了,起床了。");
    }
}

//  校园厨师类(处理事件类二)  
public class HandleEventOfChefs
{
    // 默认构造函数
    public HandleEventOfChefs()
    {
    }

    //叫厨师做早餐
    public void Cook()
    {
        Console.WriteLine("[厨师]:听到起床铃声响了,为学生做早餐。");
    }
}

// 主类
public class ListenerEvent
{
    public static void Main(String[] args)
    {
        Ring ring = new Ring(); // 实例化一个铃声类[它是主角,都是因为它才牵连一系列的动作]  
        ring.doIt += new HandleEventOfStudents().GetUp; // 注册,学生委托铃声类,铃声响起的时候叫我起床.
        ring.doIt += new HandleEventOfChefs().Cook;     // 注册,厨师告诉铃声类,我也委托你叫我什么时候做早餐
        ring.RaiseEvent(); // 铃声响起来了,它发现学生和厨师都拜托(注册)了自己,然后它就开始叫学生起床,叫厨师做早餐(一个事件调用了两个委托)
    }
}

你可能发现,上面的注册代码和前面的例子都不一样。这是因为 ring.doIt 本来就是 DoSomething 类型的,C# 会自动把学生类方法转换成相同的类型(猜测,但是上面的代码可以完美运行)。当然上面的注册代码也可以写成和文章例子的一样。 改成这样 ring.doIt += new Ring.DoSomething(new HandleEventOfStudents().GetUp); 这样也可以实现,当然这样的话定义委托的语句就要写在 Ring 类里面了。

2425C# 事件(Event)

就第一篇笔记的具体实现:

using System;
namespace CarEvent
{
    public class Car
    {
        // 申明委托
        public delegate void CarEngineHandler(string msg);
        // 创建委托实例Exploded和AboutToBlow事件
        public event CarEngineHandler Exploded;
        public event CarEngineHandler AboutToBlow;
        //设置属性
        public int CurrentSpeed { get; set; }
        public int MaxSpeed { get; set; }
        public string PetName { get; set; }
        public bool CarIsDead;//用于判断是否超速
        
        public Car()//构造函数
        {
            MaxSpeed = 100;
        }

        public Car(string name, int maxSp, int currSp)//构造函数重载

        {
            CurrentSpeed = currSp;
            MaxSpeed = maxSp;
            PetName = name;
        }

        public void Accelerate(int delta)//用于触发Exploded和AboutToBlow事件
        {            
            CurrentSpeed += delta;//"踩油门"加速
            if (CurrentSpeed >= MaxSpeed)//判断时速  
                CarIsDead = true;    
            else
                CarIsDead = false;
            if (CarIsDead)// 如果Car超速了,触发Exploded事件
            {
                if (Exploded != null)//判断是否被委托联系起来
                {
                    Exploded("sorry,this car is dead");//调用CarDead事件
                }
            }
            else
            {    //如果没有超速,则提示快要超速并显示实时车速
                if ((MaxSpeed - CurrentSpeed) > 0 && (MaxSpeed - CurrentSpeed) <= 10 && AboutToBlow != null)//判断是否被委托联系起来且速度是否接近临界值
                {
                    AboutToBlow("careful buddy ! gonna blow !");//调用NearDead事件 
                    Console.WriteLine("CurrentSpeed={0}",CurrentSpeed);//显示实时车速
                }
            }
        }
    }

    //订阅类书写举例
    public class Answer
    {
        public void CarDead(string msg)//汽车已爆缸事件
        {
            Console.WriteLine("sorry,this car is dead");
        }

        public void NearDead(string msg)//汽车快要爆缸事件
        {
            Console.WriteLine("careful buddy ! gonna blow !");
        }
    }

    //主函数书写
    public class test
    { 
        static void Main(string[] args)
        { 
            Car c = new Car("奔驰",100,93);//创建实例并初始化,初始速度为93
            Answer an = new Answer();
            c.Exploded += new Car.CarEngineHandler(an.CarDead);//Exploded"绑定"CarDead
            c.AboutToBlow += new Car.CarEngineHandler(an.NearDead);//AboutToBlow"绑定"NearDead
            c.Accelerate(6);//第一次加速,时速小于100,引发的事件为"快要爆缸"并显示实时车速为99
            Console.ReadLine();//等待回车键已启动第二次加速
            c.Accelerate(2);//第二次加速,时速超过100,引发的事件为"已爆缸",不显示车速
            Console.ReadKey();
        }
    }
}

结果为:

"careful buddy ! gonna blow !"
"CurrentSpeed=99"
(空行)(一定要记得敲一下回车键,不然不会显示下面字符串)
"sorry,this car is dead"

2424C# 事件(Event)

一个最简单的例子,不带参数的事件。是实例 2 的一个简化版:

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

namespace BoilerEvent_tz
{

    class DelegateTest 
    {
        public delegate void delegate_tz();

        public event delegate_tz delegate_tz0;

        public void start()
        {
            Console.WriteLine("启动事件");
            delegate_tz0();      // 得调用该事件呀
            Console.ReadKey();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            DelegateTest DelegateTest0 = new DelegateTest();
            //DelegateTest0.delegate_tz0 += DelegateTest.delegate_tz(test);  // 必须new一下才行,因为它是另外一个类呀
            DelegateTest0.delegate_tz0 += new DelegateTest.delegate_tz(test);
            DelegateTest0.start();                                                  // 启动事件

        }

        static public void test()
        {
            Console.WriteLine("这是一个被注册的函数,按任意键继续...");
            Console.ReadKey();
        }
    }
}

2423C# 事件(Event)

写一个最简单的使用事件的代码。帮助理解。

public class Car
{
    // 这个委托用来与Car事件协作
    public delegate void CarEngineHandler(string msg);

      // 这种汽车可以发送这些事件
    public event CarEngineHandler Exploded;
    public event CarEngineHandler AboutToBlow;

    public int CurrentSpeed { get; set; }

    public int MaxSpeed { get; set; }

    public string PetName { get; set; }

    private bool CarIsDead;

    public Car()
    {
        MaxSpeed = 100;
    }

    public Car(string name, int maxSp, int currSp)
    {
        CurrentSpeed = currSp;
        MaxSpeed = maxSp;
        PetName = name;
    }

    public void Accelerate(int delta)
    {
        // 如果Car无法使用了,触发Exploded事件
        if (CarIsDead)
        {
            if (Exploded != null)
            {
                Exploded("sorry,this car is dead");
            }
        }
        else
        {
            CurrentSpeed += delta;

            // 确认已无法使用,触发AboutToBlow事件
            if ((MaxSpeed - CurrentSpeed) == 10 && AboutToBlow != null)
            {
                AboutToBlow("careful buddy ! gonna blow !");
            }

            if (CurrentSpeed >= MaxSpeed)
            {
                CarIsDead = true;
            }
            else
            {
                Console.WriteLine(@"$CurrentSpeed={CurrentSpeed}");
            }
        }
    }
}

2422C# 委托(Delegate)

定义一个委托,准备相应的调用方法。注意:定义一个委托相当于定义一个新类,所有可以定义类的地方都可以定义委托。下面的代码定义在入口所在的类下面。

delegate double ProcessDelegate(double a, double b); // 定义一个委托。

static double Multiply(double a, double b)
{ return a * b; }

static double Divide(double a, double b)
{ return a / b; }

static double Sum(double c, double d)
{ return c + d; }

public static void Main(string[] args)
{
    ProcessDelegete MyDelegate;
    MyDelegate =  Multiply;
}