今天在博客园看到一些委托事件的东西,想想自己也看了挺多的委托事件列子,但项目并没有怎么用得到,在这里就自己写写一点我自己关于简单的委托事件的认识.

1.最简单能想象得到的委托,大概是长这样子的

namespace DelegateDemo
{

    //直接暴露在命名空间之下
    public delegate void ToSaydelegate(string content);
    static class Program
    {
        private static  string content;
        public static string Content
        {
            get { return content; }
            set { content = value; }
        }
        public static void ToCome(ToSaydelegate del)
        {
            del(content);
        }
        static void Main(string[] args)
        {

            //一种写法
            ToSaydelegate dele = new ToSaydelegate(sayHello);
            dele += sayGoodby;
            dele.Invoke("内容\n");

            //委托可以作为参数传递
            content = "content\n";
            ToCome(dele);
        }
        public static void sayHello(string content)
        {
            Console.Write("sayHello "+content);
        }
        public static void sayGoodby(string content)
        {
            Console.Write("sayGoodby " + content);
        }
    }
}

在main函数中直接实例化委托对象,将对应签名的方法作为参数传递,多个方法使用+=,-=方法增加或删除.然后委托对象实例直接调用.在ToCome方法中,证明可以将委托作为参数传递.

2.对委托的保护,加入了事件

namespace ExtDelegate
{
    public class App
    {

       //委托不再暴露
        public delegate void Sleepdelegate();

       //声明事件变量用于访问
        public event Sleepdelegate SleepEvent;
        public void Going()
        {
           
            if(SleepEvent!=null)
            {
                SleepEvent();
            }
        }
    }

    public class dog
    {
        public void Call()
        {
            Console.Write("狗叫了");
        }
    
     }

    public class thief
    {
        public void Run()
        {
            Console.Write("小偷跑了");
        }
    }

    public class host
    {
        public void awake()
        {
            Console.Write("主人醒了");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            App app = new App();
            app.SleepEvent+=(new dog()).Call;
            app.SleepEvent+=(new thief()).Run;
            app.SleepEvent+=(new host()).awake;

            app.Going();
            Console.ReadKey();
        }
    }
}

在这里使用了无返回值也无参数的简单委托签名.

3.实现一个带参数无返回值的委托签名

namespace MyDelegate
{
    public class Heater
    {
        private int tempNumber;

        public int TempNumber
        {
            get { return tempNumber; }
            set { tempNumber = value; }
        }
        //委托存在于类里面
        public delegate  void boildelegate(int num);

       //委托类型的事件变量
        public event  boildelegate BoliEvent;


        public void BoilWater()
        {
            for (int i = 80; i <=100; i++)
            {
                tempNumber = i;
                if (BoliEvent != null)
                {
                    BoliEvent(tempNumber);
                }
            }
           
        }
    }
    public class Alarm
    {
        public void OutputInfo(int t)
        {
          if(t<=90)
          {
              Console.Write("正在快速加热\n");
          }
          else if(100>t && t>95)
           {
               Console.Write("即将停止加热\n");
           }
        }
    }
    public static class Message
    {
        public static void DispalyMessage(int t)
        {
            if(t==100)
            {
                Console.Write("已经停止加热\n");
            }
           
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Heater heater = new Heater();
            
            heater.BoliEvent += (new Alarm()).OutputInfo;
            heater.BoliEvent += Message.DispalyMessage;

            heater.BoilWater();
            Console.ReadKey();
        }
    }
}

在main()中不能直接访问到委托类了,但暴露了一个事件来代替,照样能使用+=,-=,并且不能将其赋予null值.

4..Net FrameWork的规范写法

namespace Net_Delegate_Event
{
    public class Cool
    {
        //一些可以被访问的数据
        public string typeName = "Name";
        private int tempNumber;

        public int TempNumber
        {
            get { return tempNumber; }
            set { tempNumber = value; }
        }

       //委托名后加delegate,并且委托签名为void,带两个参数object(引用数据源对象,EventArgs或子类)
        public delegate void coolerdelegate(object sender, CoolerEventArgs e);

       //将将委托名的delegate去掉剩余部分加上Event
        public event coolerdelegate coolerEvent;

       //封转关键的被用于访问的数据源变量数据temp
        public class CoolerEventArgs : EventArgs
        {
            public readonly int temp;
            public CoolerEventArgs(int t)
            {
                this.temp = t;
            }
        }

       //子类可以重写
        public virtual void onCooled(CoolerEventArgs e)
        {

            if (coolerEvent != null)
            {
                coolerEvent(this, e);
            }
        }
        public void toCool()
        {
            for (int i = 4; i >= 0; i--)
            {
                tempNumber = i;
                CoolerEventArgs e = new CoolerEventArgs(tempNumber);
                onCooled(e);
            }

        }
    }

    public class Alarm
    {
        public void ToAlarm(object sender, Net_Delegate_Event.Cool.CoolerEventArgs e)
        {
            Cool cool = (Cool)sender;
            Console.Write("TypeName:"+cool.typeName+"\n温度:"+e.temp+"\n");
        }
    }

    public class ToMessage
    {
        public void toDisplay(object sender,Cool.CoolerEventArgs e)
        {
            Cool cool = (Cool)sender;
          if(e.temp==0)
          {
              Console.Write(cool.typeName+"冷却完成\n");
          }
        }
    }

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

            Cool cool = new Cool();
            cool.coolerEvent += (new Alarm()).ToAlarm;
            cool.coolerEvent += (new ToMessage()).toDisplay;

            cool.toCool();
            Console.ReadKey();
        }
    }
}

posted on 2015-08-27 22:33  巴夫巴夫  阅读(162)  评论(0编辑  收藏  举报