c#委托与事件

1.委托

委托是一种引用类型,表示对具有特定参数列表和返回类型的方法的引用

访问权限 delegate 返回值类型 委托名(参数类型)

namespace Program
{
    //以下是定义了四个委托
    public delegate int Mydelegate1(int a);
    public delegate int Mydelegate2(int a, int b);

    public delegate void Mydelegate3();
    public delegate void Mydelegate4(string str);
    class Program
    {

        static void Main(string[] args)
        {
            TestData td = new TestData();
            td.AddNum(10);
            Console.WriteLine(td.num);
        }
    }

    class TestData
    {
        public int num;
        public int AddNum(int a)
        {
            num += a;
            return num;
        }
        public int MulNum(int a, int b)
        {
            num *= (a + b);
            return num;
        }
    }
}

1.正常委托形式

    class Program
    {
        static void Main(string[] args)
        {
            //正常委托形式
            Mydelegate m1 = new Mydelegate(td.AddNum);
            Console.WriteLine(m1(10));
        }
    }

2.使用匿名函数形式与lambda表达式

 * 匿名函数
 * 提供了一种传递代码块作为委托参数的技术,匿名函数是没有方法名,只有函数主体,在匿名函数中不需要指定返回值类型,系统会在函数体中通过return语句自动推断
 * 匿名函数只能将方法赋值给委托,通过委托调用该方法

    class Program
    {
        static void Main(string[] args)
        {
            //匿名函数形式
            Mydelegate m11 = new Mydelegate(delegate(int a)
            {
                return a;
            });
            Console.WriteLine(m11(120));
    
            //lambda表达式
            Mydelegate m12 = new Mydelegate((int a) =>
            {
                return a;
            });
            Console.WriteLine(m12(12000));
        }
    }

3.系统提供的委托形式

 * Func:有返回值
 * Action:无返回值
 * Predicate:返回值为bool

    class Program
    {
        static void Main(string[] args)
        {
            //采用系统提供的委托 func
            //Func<int,int,int> 前两个int为形参类型,最后的int为返回值类型
            Func<int, int> f1 = new Func<int, int>(delegate(int a)
            {
                return a;
            });
            Console.WriteLine(f1(10));

            Func<int, int> f2 = new Func<int, int>((int a) =>
            {
                return a;
            });
            Console.WriteLine(f2(20));

            //只有一条语句时,在方法体就不需要大括号和return语句,编译器会自动补全
            Func<int, int> f3 = new Func<int, int>(a => a);
            Console.WriteLine(f2(30));

            //采用系统提供的委托 action
            //Action<int> int 为形参类型
            Action<int> a1 = new Action<int>(delegate(int a)
            {
                Console.WriteLine(a);
            });
            a1(50);
            Action<int> a2 = new Action<int>((int a) =>
            {
                Console.WriteLine(a);
            });
            a2(100);
        }
    }

4.多播委托

只有相同类型的委托才可以被合并

    class Program
    {
        static void Main(string[] args)
        {
            Test t = new Test();
            t.StartBook();
            t.ReadBood();
            Mydelegate3 m3 = new Mydelegate3(t.StartBook);
            Mydelegate3 m4 = new Mydelegate3(t.ReadBood);
            //Mydelegate3 m5 = m3 + m4;//多播委托
            //m5();
            m4 += m3;
            m4();
            m4 -= m3;
            m4();
        }
    }
    class Test
        {
            public void StartBook()
            {
                Console.WriteLine("打开书本");
            }
            public void ReadBood()
            {
                Console.WriteLine("开始读书");
            }
        }

2.事件

事件是一种特殊的委托,委托是事件的基础,本质上来讲事件就是委托。

事件是一种具有特殊签名的委托

如果说委托是对方法的包装,那么事件就是对委托进一步的包装,提升了使用的安全性,事件是安全版的委托。

下面通过一个设计模式---观察者模式来举例

    class Program
    {
        static void Main(string[] args)
        {
            Cat cat = new Cat();
            Mouse mouse = new Mouse();
            Person person = new Person();
            //注册事件
            cat.Catcall += new CatCallEventHandler(mouse.MouseRun);
            cat.Catcall += new CatCallEventHandler(person.WakeUp);
            cat.OnCatCall();
        }
    }
    //类外创建一个委托
    public delegate void CatCallEventHandler();
    class Cat
    {
        //创建事件
        public event CatCallEventHandler Catcall;
        public void OnCatCall()
        {
            Console.WriteLine("猫叫了一声");
            if (Catcall != null)
            {
                //Catcall();
                Catcall.Invoke();//invoke方法是用于多线程环境中跨线程调用委托,主要作用就是将委托的执行转移到与创建委托线程不同的线程上
            }
        }
    }
    class Mouse
    {
        public void MouseRun()
        {
            Console.WriteLine("老鼠跑了");
        }
    }
    class Person
    {
        public void WakeUp()
        {
            Console.WriteLine("人从梦中惊醒");
        }
    }

  • 18
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值