• .NET高级技术_02委托、lambda、事件


    一:委托的概念

    委托是一种可以指向方法的数据类型,可以声明委托类型变量。

    声明委托的方式:delegate 返回值类型 委托类型名(参数)
    比如:delegate void MyDel(int i);

    注意这里的除了前面的delegate,剩下部分和声明一个函数一样,但是MyDel不是函数名,而是委托类型名。

    如何创建委托类型的对象:
    MyDel sp = new MyDel (SayHello); //SayHello需要和MyDel的参数返回值一样;sp这个委托变量就指向SayHello这个方法。
    注意不要写成new Mydel (SayHello())因为加上()就是调用方法了。

    简化的方法:MyDel sp = SayHello;
    编译器会给搞成new Mydel(SayHello),反编译看看。注意不要写成MyDel sp = SayHello();

    委托的使用:委托变量之间可以互相赋值,就是一个传递指向方法的过程;sp()就是调用指向的方法,如果有参数就传递参数。

    委托是引用类型,可以为null,如果委托变量是null,那么如果调用的话,就会抛出NullReferenceException。

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Reflection;
    
    namespace NS
    {
        public delegate void MyDel1(int i);
        public delegate int MyDel2(int i, string s);
        public delegate string MyDel3();
    
        internal class Program
        {
            static void Main(string[] args)
            {
                不能写成new MyDel(M1()); 因为()代表调用方法
                //MyDel1 d1 = new MyDel1(M1);  //声明一个MyDel类型的变量d1,new MyDel(M1)创建一个指向M1方法的委托对象。
                //Console.WriteLine(d1);
                //d1(10);  //调用d1指向的方法
                //MyDel2 d2 = new MyDel2(M2);
                //int i1 = d2(10, "abc");
                //Console.WriteLine("i1 = " + i1);
    
                //MyDel3 d3 = new MyDel3(M3);
                //Console.WriteLine(d3);
                //Console.WriteLine(d3());  //加括号和不加括号的区别!
                //d3 = new MyDel3(M4);
            
    
                MyDel3 d3 = M3;  //等价于MyDel3 d3 = new MyDel3(M3);
                Console.WriteLine(d3());
                Console.ReadLine();
            }
    
            static void M1(int i)
            {
                Console.WriteLine("i = " + i);
            }
    
            static int M2(int i, string str)
            {
                return i + 10;
            }
    
            static string M3()
            {
                return "M3";
            }
    
            static string M4()
            {
                return "M4";
    
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    二:委托的应用

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Reflection;
    
    namespace NS
    {
        delegate bool CompareFunc(object obj1, object obj2);
    
        internal class Program
        {
            static void Main(string[] args)
            {
                //int[] objs = new int[] { 1, 2, 4, 4, 2, 1, 2, 3 };  //int[]无法直接转换为object[]
                //object[] objs = { 1, 2, 4, 4, 2, 1, 2, 3 };
                object[] objs = { 1.1, 2.2, 4.3, 4.4, 2.5, 1.6, 2.7, 3.8 };
                //object o1 = GetMax(objs, CompareInt);
                object o1 = GetMax(objs, new CompareFunc(Compare));
                Console.WriteLine(o1);
    
                Person p1 = new Person();
                p1.Name = "lilei";
                p1.Age = 10;
    
                Person p2 = new Person();
                p2.Name = "hanmeimei";
                p2.Age = 20;
    
                Person p3 = new Person();
                p3.Name = "polly";
                p3.Age = 30;
    
                Person[] sites = new Person[] { p1, p2, p3 };
                object obj1 = GetMax(sites, ComparePerson);
                Person person = obj1 as Person;
                Console.WriteLine(person.ToString()) ;
                Console.ReadLine();
            }
    
            static bool Compare(object obj1, object obj2)
            {
                dynamic first = obj1, second = obj2;
                return first > second;
            }
    
            static bool ComparePerson(object obj1, object obj2)
            {
                Person p1 = obj1 as Person;
                Person p2 = obj2 as Person;
                return p1.Age > p2.Age;
            }
    
            static object GetMax(object[] nums, CompareFunc func)
            {
                object max = nums[0];
                for (int i = 0; i < nums.Length; i++)
                {
                    if (func(nums[i], max))
                    {
                        max = nums[i];
                    }
                }
                return max;
            }
        }
    
        class Person
        {
            public string Name { get; set; }
            public int Age { get; set; }
    
            public override string ToString()
            {
                return "Name = " + Name + ", Age = " + Age;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    namespace NS
    {
        delegate T MyDel<T>(T t);
        internal class Program
        {
            static void Main(string[] args)
            {
                MyDel<int> mydel1 = Func1;
                Console.WriteLine(mydel1(20));
                Console.ReadLine();
            }
    
            static int Func1(int i)
            {
                return i + 10;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    三:Func、Action

    .Net中内置两个泛型委托Func、Action(在“对象浏览器”的mscorlib的System下),日常开发中基本不用自定义委托类型了。
    Func是有返回值的委托;Action是没有返回值的委托。
    测试一下用Func、 Action代替之前的委托。

    namespace NS
    {
        //delegate void Dele1();
        internal class Program
        {
            static void Main(string[] args)
            {
                //Dele1 d1 = Func1;
                Action action1 = Func1;
                action1();
                Func<int, int, bool> func1 = CompareInt;
                Console.WriteLine(func1(3, 5));
                Console.ReadLine();
            }
    
            static void Func1()
            {
                Console.WriteLine("Func1");
            }
            static bool CompareInt(int i1, int i2)
            {
                return i1 > i2;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    四:匿名方法

    使用Delegate的时候很多时候没必要使用一个普通的方法,因为这个方法只有这个Delegate会用,并且只用一次,这时候使用匿名方法最合适。

    匿名方法就是没有名字的方法。定义语法:MyDelegate p = delegate(int s){s=10;};

    使用匿名方法改造GetMax方法:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Reflection;
    
    namespace NS
    {
        delegate bool Mydele1(int i, string s);
        delegate bool CompareFunc(object obj1, object obj2);
        internal class Program
        {
            static void Main(string[] args)
            {
                Mydele1 d1 = Func1;
                Mydele1 d2 = delegate (int i, string str)
                {
                    Console.WriteLine("i = " + i + ", str = " + str);
                    return true;
                };
                bool b1 = d2(5, "lilei");
                Console.WriteLine(b1);
    
                object[] objs = new object[] { 1, 2, 4, 4, 2, 1, 2, 3 };  //int[]无法直接转换为object[]
                CompareFunc f1 = delegate (object obj1, object obj2)
                {
                    dynamic first = obj1, second = obj2;
                    return first > second;
                };
                object obj = GetMax(objs, f1);
                Console.WriteLine(obj);
                Console.ReadLine();
            }
    
            static bool Func1(int i, string str)
            {
                Console.WriteLine("i = " + i + ", str = " + str);
                return true;
            }
    
            static object GetMax(object[] nums, CompareFunc func)
            {
                object max = nums[0];
                for (int i = 0; i < nums.Length; i++)
                {
                    if (func(nums[i], max))
                    {
                        max = nums[i];
                    }
                }
                return max;
            }
        } 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    五:lambda表达式

    函数式编程,在Entity framework编程中用的很多

    1、Action a1 = delegate(int i) { Console.WriteLine(i); };
    可以简化成(=>读作goes to)
    Action a2 = (int i) => { Console.WriteLine(i); };

    2、可以省略参数类型(编译器会自动根据委托类型推断)。
    Action a3 = (i) => { Console.WriteLine(i); };
    如果只有一个参数还可以省略参数的小括号(多个参数不行)
    Action a4 = i => { Console.WriteLine(i); };

    3、如果委托有返回值,并且方法体只有一行代码,这一行代码还是返回值,那么就可以连方法的大括号和return都省略:
    Func f1 = delegate(int i, int j) { return “结果是” + (i + j); };
    Func f2= (i,j)=>“结果是”+(i+j);

    4、普通匿名类型也是一样用lambda表达式。

    internal class Program
    {
        static void Main(string[] args)
        {
            Action<int> a1 = delegate (int i) { Console.WriteLine(i); };
            Action<int> a2 = (int i) => { Console.WriteLine(i); };
            Action<int> a3 = i => { Console.WriteLine(i); };
    
            Func<string, int, bool> f1 = delegate (string s, int i) { return true; };
            Func<string, int, bool> f2 = (string s, int i) => { return true; };
            Func<string, int, bool> f3 = (s, i) => { return true; };
            Func<string, int, bool> f4 = (s, i) => true;
    
            Console.ReadLine();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    namespace NS
    {
        internal class Program
        {
            static void Main(string[] args)
            {
                int[] nums = new int[] { 1, 2, 4, 4, 2, 1, 2, 3 };
                //int i_max = GetMax(nums, CompareInt);
                //int i_max = GetMax(nums, delegate (int i1, int i2) { return i1 > i2; });
                int i_max = GetMax(nums, (i1, i2) => i1 > i2);
                Console.WriteLine(i_max);
    
                Person p1 = new Person();
                p1.Name = "lilei";
                p1.Age = 10;
    
                Person p2 = new Person();
                p2.Name = "hanmeimei";
                p2.Age = 20;
    
                Person p3 = new Person();
                p3.Name = "polly";
                p3.Age = 30;
    
                Person[] sites = new Person[] { p1, p2, p3 };
    
                Person p = GetMax<Person>(sites, (p1, p2) => p1.Age > p2.Age);
                Console.WriteLine(p);
                Console.ReadLine();
            }
    
            static bool CompareInt(int i1, int i2)
            {
                return i1 > i2;
            }
    
            static T GetMax<T>(T[] objs, Func<T, T, bool> compareFunc)
            {
                T max = objs[0];
                for (int i = 0; i < objs.Length; i++)
                {
                    if (compareFunc(objs[i], max))
                    {
                        max = objs[i];
                    }
                }
                return max;
            }
        }
    
        class Person
        {
            public Person()
            {
                
            }
    
            public Person(string name, int age)
            {
                Name = name;
                Age = age;
            }
    
            public string Name { get; set; }
            public int Age { get; set; }
    
            public override string ToString()
            {
                return "Name = " + Name + ", Age = " + Age;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    namespace NS
    {
        internal class Program
        {
            static void Main(string[] args)
            {
                int[] nums = new int[] { 1, 2, 4, 4, 2, 1, 2, 3 };
                //IEnumerable list = nums.MyWhere(i => i > 2);
                IEnumerable<int> list = nums.MyWhere(i => i % 2 == 0);
                foreach (var item in list)
                {
                    Console.WriteLine(item);
                }
    
                string[] strs = new string[] { "tom", "jim", "lily", "hanmeimei" };
                foreach (var name in strs.MyWhere(s => s.Contains("m")))
                {
                    Console.WriteLine(name);
                }
                Console.ReadLine();
            }
        }
    
        public static class JiHeExt
        {
            public static IEnumerable<T> MyWhere<T>(this IEnumerable<T> data, Func<T, bool> func)
            {
                List<T> resultList = new List<T>();
                //foreach()面试题:什么样的对象可以使用foreach遍历?
                //实现了IEnumreable接口。List,数组等都实现了IEnumerable接口
                foreach (var item in data)
                {
                    if (func(item))
                    {
                        resultList.Add(item);
                    }
                }
                return resultList;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    六:集合常用扩展方法

    Where(支持委托):是对数据按照lambda表达式进行过滤。

    Select(支持委托):是对集合中的数据进行处理,生成一个新的集合,集合长度和原始集合长度一致。

    Max、Min、Sum、Average

    OrderBy

    namespace NS
    {
        internal class Program
        {
            static void Main(string[] args)
            {
                List<int> list = new List<int>() { 3, 9, 8, 16, 90 };
                //IEnumerable data = list.Where(x => x > 10);
                //IEnumerable data = list.Select(x => x * 10);
                IEnumerable<string> data = list.Select(x => "hello: " + x);
                Console.WriteLine(data.GetType());  //返回实现该接口的类
                foreach (var item in data)
                {
                    Console.WriteLine(item);
                }
    
                int max = list.Max();
                int min = list.Min();
                int sum = list.Sum();
                double average = list.Average();
                Console.WriteLine("max = " + max + ", min = " + min + ", sum = " + sum + ", average = " + average);
    
                Console.WriteLine("====================================");
    
                foreach (var item in list.OrderBy(i => i))
                {
                    Console.WriteLine(item);
                }
    
                Console.WriteLine("====================================");
    
                Person p3 = new Person();
                p3.Name = "polly";
                p3.Age = 30;
    
                Person p1 = new Person();
                p1.Name = "lilei";
                p1.Age = 10;
    
                Person p2 = new Person();
                p2.Name = "hanmeimei";
                p2.Age = 20;
    
                Person[] sites = new Person[] { p1, p2, p3 };
    
                int age_sum1 = sites.Sum(p => p.Age);
                int age_sum2 = sites.MySum(p => p.Age);
                int age_sum3 = sites.MySum(p => p.Name.Length);
    
                Console.WriteLine(age_sum1);
                Console.WriteLine(age_sum2);
                Console.WriteLine(age_sum3);
    
                //foreach (var item in sites.OrderBy(p => p.Age))
                foreach (var item in sites.OrderBy(p => p.Name.Length))
                {
                    Console.WriteLine(item);
                }
    
                List<Person> ps1 = sites.OrderBy(p => p.Age).ToList();
                Person[] ps2 = sites.OrderBy(p => p.Age).ToArray();
                List<Person> ps3 = sites.ToList();
                Person[] ps4 = ps3.ToArray();
    
                Console.ReadLine();
            }
        }
    
        class Person
        {
            public Person()
            {
    
            }
    
            public Person(string name, int age)
            {
                Name = name;
                Age = age;
            }
    
            public string Name { get; set; }
            public int Age { get; set; }
    
            public override string ToString()
            {
                return "Name = " + Name + ", Age = " + Age;
            }
        }
    
        public static class MyEx
        {
            public static int MySum<T>(this IEnumerable<T> data, Func<T, int> func)
            {
                int sum = 0;
                foreach (var item in data)
                {
                    sum += func(item);
                }
                return sum;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103

    First:获取第一个,如果一个都没有则异常
    FirstOrDefault:获取第一个,如果一个都没有则返回默认值
    Single:获取唯一一个,如果没有或者有多个则异常
    SingleOrDefault:获取唯一一个,如果没有则返回默认值,如果有多个则异常
    ToList、ToArray

    namespace NS
    {
        internal class Program
        {
            static void Main(string[] args)
            {
                string[] strs1 = { };
                string[] strs2 = { "lilei" };
                string[] strs3 = { "lilei", "hanmeimei" };
    
                List<int> list1 = new List<int>();
                //int i = list1.First();
                Console.WriteLine(list1.FirstOrDefault());
    
                //string s1 = strs1.First();  //获取集合中的第一个元素,如果一个元素都没有,则抛异常
                Console.WriteLine(strs2.First());
                string s1 = strs1.FirstOrDefault();  //获取集合中的第一个元素,如果一个元素都没有,则返回类型的默认值
    
                string s2 = strs2.Single();  //获取集合中的唯一一个元素,如果没有元素或者有不止一个元素,则抛异常
                string s3 = strs2.SingleOrDefault();  //获取集合中的唯一一个元素,如果没有元素则返回null,
                                                      //如果有多个元素,则抛异常
                Console.WriteLine("====================================");
    
                List<int> list2 = new List<int>() { 3, 9, 8, 90, 10, 35 };
                foreach (var item in list2.Where(i => i > 7).OrderBy(i => i).Select(i => i + 10))
                {
                    Console.WriteLine(item);
                }
                int max = list2.Where(i => i > 7).Max();
                Console.WriteLine(max);
    
                Console.ReadLine();
            }
        }
    
        class Person
        {
            public Person()
            {
    
            }
    
            public Person(string name, int age)
            {
                Name = name;
                Age = age;
            }
    
            public string Name { get; set; }
            public int Age { get; set; }
    
            public override string ToString()
            {
                return "Name = " + Name + ", Age = " + Age;
            }
        }
    
        public static class MyEx
        {
            public static int MySum<T>(this IEnumerable<T> data, Func<T, int> func)
            {
                int sum = 0;
                foreach (var item in data)
                {
                    sum += func(item);
                }
                return sum;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70

    七:委托的组合

    委托对象可以“+相加”,调用组合后的新委托对象会依次调用被组合起来的委托:MyDel m5 = m1+m2+m3;
    组合的委托必须是同一个委托类型。

    委托的“-”则是从组合委托中把委托移除;

    委托如果有返回值,则有一些特殊。委托的组合一般是给事件用的,用普通的委托的时候很少用。

    namespace NS
    {
        delegate void MyDel(int i);
        internal class Program
        {
            static void Main(string[] args)
            {
                MyDel d1 = F1;  //MyDel d1 = new MyDel(F1);
                MyDel d2 = F2;
                MyDel d3 = F3;
                MyDel d4 = d1 + d2 + d3;
                MyDel d5 = new MyDel(F1) + new MyDel(F2) + new MyDel(F3);
                d4(10);
                d4 = d4 - d2;
                Console.WriteLine("第二次调用d4");
                d4(20);
                Console.ReadLine();
            }
    
            static void F1(int i)
            {
                Console.WriteLine("我是f1:" + i);
            }
    
            static void F2(int i)
            {
                Console.WriteLine("我是f2:" + i);
            }
    
            static void F3(int i)
            {
                Console.WriteLine("我是f3:" + i);
            }
        } 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    八:事件

    案例:定义一个Person类,定义一个监听年龄变化的事件,当本命年的时候祝贺一下。触发事件的地方要判断一下是不是事件null。

    事件语法:event Mydelegate mdl;

    加了event关键字实现事件机制的好处:用了event事件,不可以修改事件已经注册的值;不可以冒充进行事件通知了。只能+=、-=!

    namespace NS
    {
        internal class Program
        {
            static void Main(string[] args)
            {
                Person p1 = new Person();
                p1.OnBenMingNian += BMN;  //方法的参数返回值要和事件的委托一致\
                p1.OnBenMingNian += BMN2;
                p1.OnBenMingNian = null;
                p1.Age = 5; 
                Console.WriteLine(p1.Age);
                p1.Age = 24;
                Console.WriteLine(p1.Age);
                Console.ReadLine();
            }
    
            static void BMN()
            {
                Console.WriteLine("BMN()到了本命年了!");
            }
    
            static void BMN2()
            {
                Console.WriteLine("BMN2()到了本命年了!");
            }
        }
    
        class Person
        {
            private int _Age;
    
            public int Age
            {
                get { return _Age; }
                set
                {
                    _Age = value;
                    if (_Age % 12 == 0)
                    {
                        if (OnBenMingNian != null)
                        {
                            OnBenMingNian();
                        }
                    }
                }
            }
    
            //public event Action OnBenMingNian;  //event 委托类型事件的名字;
    
            public Action OnBenMingNian;  //event 委托类型事件的名字;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    九:委托和事件的总结

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

    事件的作用:事件的作用与委托变量一样,只是功能上比委托变量有更多的限制。(比如:1.只能通过+=或-=来绑定方法(事件处理程序)2.只能在类内部调用(触发)事件。)

    (面试题)事件和委托的关系:事件由一个私有的委托变量和add_***和remove_***方法组成;
    事件的非简化写法:声明一个私有的委托变量和add、remove方法。

    委托和事件的区别和关系

    一种错误的说法“事件是一种特殊的委托”,事件是由一个私有委托和add、remove两个方法组成的。
    委托用的比较多,事件只有开发WinForm、WPF的时候用的才比较多。

    事件、索引器、属性本质上都是方法。

    (面试题)接口中可以定义什么?
    答:接口中只可以定义方法。接口中也可以定义“事件、索引器、属性”,因为他们本质上也都是方法。

    namespace NS
    {
        internal class Program
        {
            static void Main(string[] args)
            {
                Person p1 = new Person();
                p1.OnBenMingNian += BMN;  //方法的参数返回值要和事件的委托一致\
                p1.OnBenMingNian += BMN2;
                //p1.OnBenMingNian = null;
                p1.Age = 5; 
                Console.WriteLine(p1.Age);
                p1.Age = 24;
                Console.WriteLine(p1.Age);
                Console.ReadLine();
            }
    
            static void BMN()
            {
                Console.WriteLine("BMN()到了本命年了!");
            }
    
            static void BMN2()
            {
                Console.WriteLine("BMN2()到了本命年了!");
            }
        }
    
        class Person
        {
            private int _Age;
    
            public int Age
            {
                get { return _Age; }
                set
                {
                    _Age = value;
                    if (_Age % 12 == 0)
                    {
                        //if (OnBenMingNian != null)
                        //{
                        //    OnBenMingNian();
                        //}
                        if (_OnBenMingNian != null)
                        {
                            _OnBenMingNian();
                        }
                    }
                }
            }
    
            //public event Action OnBenMingNian;  //event 委托类型事件的名字;
            //public Action OnBenMingNian;  //加上event就是事件,不加event就是委托;
    
            //事件是由私有的委托+add+remove组成
            private Action _OnBenMingNian;
            public event Action OnBenMingNian
            {
                add
                {
                    this._OnBenMingNian += value;
                }
    
                remove
                {
                    this._OnBenMingNian -= value;
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
  • 相关阅读:
    10月TIOBE榜Java跌出前三!要不我转回C#吧
    Docker容器入门笔记,一篇文章告诉你,使用docker的方法和使用Docker的优势
    node.js的路径、fs模块
    计算机网络---应用层概述
    医药制药行业有机VOCs废气治理
    jdk1.8.191 JVM内存参数 InitialRAMPercentage和MinRAMPercentage
    SpringBoot 项目实战 ~ 9.数据缓存
    123456
    MySQL—约束—演示(基础)
    Java中JVM、JRE和JDK三者有什么区别和联系?
  • 原文地址:https://blog.csdn.net/zzyzxb/article/details/126307276