c#的委托和事件的实例学习

简写

委托简而言之是将方法作为参数进行传递.

1,声明 传入参数和返回需要一致(委托逆变:委托入参为基类型)
public    string method1(string);   
public    string method2(string);                         
public  string method3(string);
public  string delegate(string);
2,添加委托
delegate dgt;
delegate dgt1 = new delegate(method1);
delegate dgt2 = new delegate(method2);
delegate dgt3 = new delegate(method3);
dgt = dgt1;//添加单路广播
//添加多路广播
dgt += dgt2;
dgt += dgt3;
3,调用
//等价于 method3(method2(method1(string)));
//调用顺序按添加前后
dgt("string");

代码学习

委托的单路广播,多路广播,委托逆变,泛型委托.以及简单的事件学习.

 //委托可以被视为一个更高级的指针,它不仅仅能把地址指向另一个函数,而且还能传递参数,返回值等多个信息
    public class ClassDelegate
    {
        //委托对象绑定单个方法。
        //无返回值
        delegate void MyDelegate1(string message);
        //有返回值
        delegate string MyDelegate2(string message);
        public class Example
        {
            public void Method1(string message)
            {
                MessageBox.Show(message);
            }

            public string Method2(string message)
            {
                return "Hello" + message;
            }
        }

        //委托对象可以绑定多个方法。
        //当输入参数后,每个方法会按顺序进行迭代处理,并返回最后一个方法的计算结果。
        delegate double MyDelegate3(double message);
        public class Price
        {
            public double Ordinary(double price)
            {
                Console.WriteLine("Ordinary Price :" + price);
                return price;
            }

            public double Discount(double price)
            {
                Console.WriteLine("Discount Price :" + price * Convert.ToDouble(Math.Abs(Convert.ToDecimal(0.75))));
                return price * Convert.ToDouble(Math.Abs(Convert.ToDecimal(0.75)));
            }
        }

        //观察者模式 让多个观察者同时关注同一个事物,并作出不同的响应
        public delegate double Handler(double basicWages);
        public class Manager
        {
            public double GetWages(double basicWages)
            {
                double totalWages = 8 * basicWages;
                MessageBox.Show(null, totalWages.ToString(), "经理工资",
                    MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                return totalWages;
            }
        }
        public class Assistant
        {
            public double GetWages(double basicWages)
            {
                double totalWages = 2 * basicWages;
                MessageBox.Show(null, totalWages.ToString(), "助理工资",
                    MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                return totalWages;
            }
        }
        public class WageManager
        {
            private Handler wageHandler;

            //加
            public void Attach(Handler wageHandlerAdd)
            {
                wageHandler += wageHandlerAdd;
            }

            //减
            public void Detach(Handler wageHandlerSub)
            {
                wageHandler -= wageHandlerSub;
            }
            //获取多路广播委托列表,如果观察者数量大于0即执行方法
            public void Execute(double basicWages)
            {
                if (wageHandler != null)
                    if (wageHandler.GetInvocationList().Count() != 0)
                        wageHandler(basicWages);
            }

        }

        //委托逆变 
        //object 为参数的委托,可以接受任何 object 子类的对象作为参数
        public delegate void HandlerObj(object obj);
        public static void GetMessage(object message)
        {
            if (message is string)
                MessageBox.Show(null, message.ToString(), "", MessageBoxButtons.RetryCancel, MessageBoxIcon.Hand);
            else if (message is int)
                MessageBox.Show(null, message.ToString(), "", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            else
                MessageBox.Show(null, "!string & !int", "", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Warning);
        }

        //泛型委托
        //可以使一个委托绑定多个不同类型参数的方法,而且在方法中不需要使用 is 进行类型判断
        public delegate void HandlerGen<T>(T obj);
        public class Coolpad
        {
            private double price;
            public double Price
            {
                get { return price; }
                set { price = value; }
            }
        }
        public class iPhone
        {
            private double price;
            public double Price
            {
                get { return price; }
                set { price = value; }
            }
        }
        public static void GetCoolpadPrice(Coolpad coolp)
        {
            MessageBox.Show(null, coolp.Price.ToString(), "酷派", MessageBoxButtons.OKCancel, MessageBoxIcon.Stop);
        }
        public static void GetiPhonePrice(iPhone ip)
        {
            MessageBox.Show(null, ip.Price.ToString(), "iPhone", MessageBoxButtons.OKCancel, MessageBoxIcon.Stop);
        }

        
        //事件
        public delegate void DelegateTest(string name);
        public class EventTest 
        {
            public event DelegateTest MyEvent;

            public void GetNameEvent(string name)
            {
                if (MyEvent == null)
                    return;
                MyEvent("My Name Is "+name);
            }
        }
        
        static void Main(string[] arggs)
        {
            #region  单路广播
            //Example ex = new Example();
            //当建立委托对象时,委托的参数类型必须与委托方法相对应。
            //只要向建立委托对象的构造函数中输入方法名称example.Method,委托就会直接绑定此方法
            //MyDelegate1 md1 = new MyDelegate1(ex.Method1);
            //md1("asdf");
            //MyDelegate2 md2 = new MyDelegate2(ex.Method2);
            //string strMd2 = md2("asdf");
            //MessageBox.Show(null,strMd2,"测试",MessageBoxButtons.OK,MessageBoxIcon.Warning);
            #endregion

            #region 多路广播
            //Price p = new Price();
            //MyDelegate3 md4 = new MyDelegate3(p.Ordinary);
            //double strMd4 = md4(100);
            //MessageBox.Show(null, strMd4.ToString(), "测试", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            //MyDelegate3 md5 = new MyDelegate3(p.Discount);
            //double strMd5 = md5(100);
            //MessageBox.Show(null, strMd5.ToString(), "测试", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            #endregion

            #region Observer 模式,
            它使用一对多的方式,可以让多个观察者同时关注同一个事物,并作出不同的响应

            //WageManager wm = new WageManager();
            观察者Manager
            //Manager m1 = new Manager();//添加经理1
            //Handler mh1 = new Handler(m1.GetWages);//创建委托,将方法作为入参
            //wm.Attach(mh1);//添加委托方法
            //Manager m12 = new Manager();
            //Handler mh12 = new Handler(m12.GetWages);
            //wm.Attach(mh12);

            观察者Assistant
            //Assistant a1 = new Assistant();
            //Handler ah1 = new Handler(a1.GetWages);
            //wm.Attach(ah1);
            //wm.Detach(mh1);

            //wm.Execute(2000);
            #endregion

            #region 委托逆变,是指委托方法的参数同样可以接收 “继承” 这个传统规则
            //4
            //委托协变 指委托直接绑定委托方法 自从Framework 2.0 面试以后,委托协变的概念就应运而生
            //HandlerObj hobj = GetMessage;
            //hobj(12);
            //hobj("12");
            //hobj(12.23);//1
            //HandlerObj hobj = new HandlerObj(GetMessage);
            //hobj(12);
            //hobj("12");
            //hobj(12.23);

            //2
            //HandlerObj hobj = delegate(object e) 
            //{
            //    GetMessage(12);
            //    GetMessage("12");
            //    GetMessage(12.25);
            //};
            //hobj(";");//没啥用

            //3
            //HandlerObj hobj = ((object sender) => 
            //{
            //    GetMessage(12);
            //    GetMessage("12啥错");
            //    GetMessage(12.25);
            //});
            //hobj(2);

            //5
            //Action<object> hobj = ((object sender) =>
            // {
            //     GetMessage(12);
            //     GetMessage("12啥错");
            //     GetMessage(12.25);
            // });
            //hobj(2);
            #endregion

            #region 泛型委托
            //Action<Coolpad> hgcp = ((Coolpad wee) =>
            //{
            //    wee.Price = 1500;
            //    GetCoolpadPrice(wee);
            //});
            //Coolpad cpa = new Coolpad();
            //cpa.Price = 10000;
            //hgcp(cpa);

            //Action<iPhone> hgip = ((iPhone wee) =>
            //{
            //    wee.Price = 3500;
            //    GetiPhonePrice(wee);
            //});
            //iPhone ipa = new iPhone();
            //ipa.Price = 10000;
            //hgip(ipa);

            //HandlerGen<Coolpad> cph = new HandlerGen<Coolpad>(GetCoolpadPrice);
            //Coolpad cp = new Coolpad();
            //cp.Price = 2000;
            //cph(cp);

            //HandlerGen<iPhone> iph = new HandlerGen<iPhone>(GetiPhonePrice);
            //iPhone ip = new iPhone();
            //ip.Price = 6000;
            //iph(ip);
            #endregion

            #region 事件测试
            //事件:事件(event)可被视作为一种特别的委托,
            //它为委托对象隐式地建立起add_XXX、remove_XXX 两个方法,用作注册与注销事件的处理方法
            EventTest eTest = new EventTest();

            //注册事件
            eTest.MyEvent += delegate(string name)
            {
                MessageBox.Show(name.ToString());
            };

            //调用
            eTest.GetNameEvent("Jack");
            
            #endregion
        }

    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值