• C#学习笔记(十七):委托、事件、观察者模式、匿名委托和lambert表达式


    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    namespace m1w4d3_delegate
    {
        //委托类型的定义
        //委托是一个引用类型,存放着一个或者一组方法的引用
        //方法的签名
        //访问修饰 关键字(delegate) 对应方法的签名(返回类型 委托名 参数)
        //public delegate void MyDelegate();
        public delegate bool MyDelegate(int a, int b);
        class Program
        {
            static void Main(string[] args)
            {
                //委托类型的定义
                MyDelegate myDelegate;//这种形式用的比较多
                //委托的实例化
                //我们可以通过委托的构造函数实例化一个委托,需要传一个同参同返回的函数参数
                MyDelegate myDelegate1 = new MyDelegate(Max);//这种形式用的比较少
                MyDelegate myDelegate2 = Max;//等同于这种形式
                //赋值
                //将委托的委托列表清空,然后将赋值的函数注册到委托列表
                //如果我们将一个函数赋值到委托
                //这个委托被调用时,等同与函数被调用
                //赋值只需要函数(方法)名,不需要传参
                myDelegate = Max;//用的比较少
                myDelegate(3, 5);
                Console.WriteLine();
                //注册
                //如果我们将一个函数注册到委托
                //相当于将函数注册到其委托列表
                //这个委托被调用时,将调用到这个注册函数  
                //注册只需要函数(方法)名,不需要传参        
                myDelegate += Min;//用的比较多
                myDelegate += Min;
                myDelegate += Min;
                myDelegate(3, 5);
                Console.WriteLine();
                myDelegate += Max;
                myDelegate += Max;
                myDelegate += Min;
                //myDelegate = Max;
                myDelegate(3, 5);
                Console.WriteLine();
                //注销
                //注册就是将一个函数从委托的委托列表中移除
                //仅移除最后一个注册的对应函数
                //如果委托列表中没有对应的函数不会报错
                myDelegate -= Max;
                myDelegate(3, 5);
                Console.WriteLine();
                //调用
                //委托会将其 委托列表 中所有的函数按顺序执行
                //通过委托我们只能取得最后的执行的函数的返回值
                //委托调用时确定其参数,虽然委托中有多个函数,但只能使用一份参数
                //委托可以通过 变量名(参数)调用,变量名.Invoke(参数)
                Console.WriteLine(myDelegate(3, 5));
                myDelegate.Invoke(3, 5);
                //作为参数的应用
                //委托可以做为另一个函数的参数使用
                //当一个函数使用了委托参数时
                //当其被调用时,我们可以直接放入一个对应委托,或者直接放入一个与委托同参同返回的函数参数
            }
            //如果一个函数和委托的约束的签名一致
            //我们就可以把这个函数赋值或注册到委托
            static bool Max(int a, int b)
            {
                Console.WriteLine("Max方法被执行了");
                return false;
            }
            static bool Min(int a, int b)
            {
                Console.WriteLine("Min方法被执行了");
                return true;
            }
        }
    }
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    namespace m1w4d3_delegate1
    {
        //设计模式 在编程的过程中,前辈们为了解决特定的通用问题而总结出来的模式
        //单例模式
        //观察者模式 用于构建 事件处理系统
        //通过一个被观察者去管理观察者
        //被观察者 通过 事件(委托) 在状态改变时 调用所用注册过的 观察者方法
        //1、委托外部调用不安全
        //2、委托外部赋值不安全
        //3、私有化之后,外部成员无法注册
        //事件是对委托的进一步封装,约束了委托访问的作用域,允许事件在外部注册,但是不能赋值和调用
        //通过在一个委托的前面加上event关键字可以定义一个事件
        //老师会在下课时打铃(事件)
        //学生们想在打铃事件发生的时候自己想做的事情
        //小明想在大龄的时候去买吃的
        //小张想在大龄的时候去打水
        //小红想在大龄的时候去开始练习
        //小花想在大龄的时候去打羽毛球
        public delegate void MyDelegate();
        class Teach//被观察者
        {
            public Teach(string name)
            {
                this.name = name;
            }
            string name;
            //public void Ring() { }
            //由一个方法,变成了一组方法的引用
            //public MyDelegate OnRing;
            //event相当于private,内部有完全访问,外部只能注册
            public event MyDelegate OnRing;
            public void Ring()
            {
                //行为:打铃行为
                Console.WriteLine("老师打铃了");
                //事件:呼叫观察者
                if (OnRing != null)
                {
                    OnRing();
                }
            }
        }
        class Student//观察者
        {
            public Student(string name)
            {
                this.name = name;
            }
            string name;
            public void Eat()
            {
                Console.WriteLine("{0}在吃东西",name);
            }
            public void Water()
            {
                Console.WriteLine("{0}在打水", name);
            }
            public void Ex()
            {
                Console.WriteLine("{0}在开始练习", name);
            }
            public void Play()
            {
                Console.WriteLine("{0}在打羽毛球", name);
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
                Student xiaoMing = new Student("小明");
                Student xiaoZhang = new Student("小张");
                Student xiaoHong = new Student("小红");
                Student xiaoHua = new Student("小花");
                xiaoMing.Eat();
                xiaoZhang.Water();
                xiaoHong.Ex();
                xiaoHua.Play();
                Teach teacher = new Teach("王老师");
                teacher.Ring();
                //当委托被私有化时,外部人员不能注册
                teacher.OnRing += xiaoMing.Eat;
                teacher.OnRing += xiaoZhang.Water;
                teacher.OnRing += xiaoHong.Ex;
                teacher.OnRing += xiaoHua.Play;
                //观察者模式,通过委托来实现,代码不严谨,原因如下:
                //1、外部可以轻易给委托赋值
                //teacher.OnRing = xiaoHua.Play;
                //2、外部可以轻易调用委托
                //teacher.OnRing();
                teacher.Ring();
            }
        }
    }
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    namespace m1w4d3_delegate2
    {
        //写一个排序的方法,他可以指定不同的排序逻辑(委托)
        //从大到小,从小到大
        public delegate bool MyDelegate(int a, int b);
        class Program
        {
            static void Main(string[] args)
            {
                int[] array = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };
               
                //一般方法
                SortMax(array);
                foreach (var item in array)
                {
                    Console.Write(item + "  ");
                }
                Console.WriteLine();
                SortMin(array);
                foreach (var item in array)
                {
                    Console.Write(item + "  ");
                }
                Console.WriteLine();
                //委托方法
                MyDelegate condition = Max;
                Sort(array, condition);
                foreach (var item in array)
                {
                    Console.Write(item + "  ");
                }
                Console.WriteLine();
                condition = Min;
                Sort(array, condition);
                foreach (var item in array)
                {
                    Console.Write(item + "  ");
                }
                Console.WriteLine();
            }
            static void SortMax(int[] array)
            {
                //外层循环Length-1次
                for (int i = 0; i < array.Length; i++)
                {
                    //内层循环Length-1-i(外层循环的当前次数)
                    for (int j = 0; j < array.Length - 1 - i; j++)
                    {
                        //如果条件(大)达成,交换位置
                        if (array[j] > array[j + 1])
                        {
                            int temp = array[j];
                            array[j] = array[j + 1];
                            array[j + 1] = temp;
                        }
                    }
                }
            }
            static void SortMin(int[] array)
            {
                //外层循环Length-1次
                for (int i = 0; i < array.Length; i++)
                {
                    //内层循环Length-1-i(外层循环的当前次数)
                    for (int j = 0; j < array.Length - 1 - i; j++)
                    {
                        //如果条件(小)达成,交换位置
                        if (array[j] < array[j + 1])
                        {
                            int temp = array[j];
                            array[j] = array[j + 1];
                            array[j + 1] = temp;
                        }
                    }
                }
            }
            static void Sort(int[] array, MyDelegate condition)
            {
                //外层循环Length-1次
                for (int i = 0; i < array.Length; i++)
                {
                    //内层循环Length-1-i(外层循环的当前次数)
                    for (int j = 0; j < array.Length - 1 - i; j++)
                    {
                        //如果条件(大)达成,交换位置
                        if (condition(array[j], array[j + 1]))
                        {
                            int temp = array[j];
                            array[j] = array[j + 1];
                            array[j + 1] = temp;
                        }
                    }
                }
            }
            static bool Max(int a, int b)
            {
                return a > b;
            }
            static bool Min(int a, int b)
            {
                return a < b;
            }
        }
    }
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    namespace m1w4d3_delegate3_lambert
    //匿名委托和lambert表达式
    {
        public delegate bool MyDelegate(int a, int b);
        class Program
        {
            static void Main(string[] args)
            {
                int[] array = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };
                //匿名委托
                //匿名委托只能作为委托的值被使用
                //缺陷
                //匿名委托可读性差,建议匿名委托语句行数不宜过多,一句最佳
                //匿名委托不可复用(违背封装原则)
                //delegate (参数) {函数体}
                MyDelegate condition = delegate (int a, int b)
                {
                    return a > b;
                };
                Sort(array, condition);
                foreach (var item in array)
                {
                    Console.Write(item +"  ");
                }
                Console.WriteLine();
                Sort(array, condition = delegate (int a, int b) { return a < b; });
                foreach (var item in array)
                {
                    Console.Write(item + "  ");
                }
                Console.WriteLine();
                //lambert表达式(匿名委托的进一步简写)
                //lambert表达式只能作为委托的值被使用
                //缺陷
                //lambert表达式可读性差,建议匿名委托语句行数不宜过多,一句最佳
                //lambert表达式不可复用(违背封装原则)
                //lambert表达式可以让你不适用类型
                //lambert表达式如果函数体只有一句语句,可以省略花括号,不写return,不写分号;
                //lambert表达式在参数只有一个的情况下可以不用括号
                //(参数)=> {函数体}
                Sort(array, (int a, int b) => { return a > b; });
                foreach (var item in array)
                {
                    Console.Write(item + "  ");
                }
                Console.WriteLine();
                Sort(array, (a, b) => a < b);
                foreach (var item in array)
                {
                    Console.Write(item + "  ");
                }
                Console.WriteLine();
            }
            static void Sort(int[] array, MyDelegate condition)
            {
                //外层循环Length-1次
                for (int i = 0; i < array.Length; i++)
                {
                    //内层循环Length-1-i(外层循环的当前次数)
                    for (int j = 0; j < array.Length - 1 - i; j++)
                    {
                        //如果条件(大)达成,交换位置
                        if (condition(array[j], array[j + 1]))
                        {
                            int temp = array[j];
                            array[j] = array[j + 1];
                            array[j + 1] = temp;
                        }
                    }
                }
            }
            static bool Max(int a, int b)
            {
                return a > b;
            }
            static bool Min(int a, int b)
            {
                return a < b;
            }
        }
    }
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    namespace m1w4d3_delegate4
    {
        public delegate void MyDelegate();
        public delegate void FighterDelegate(Fighter a);
        //战士在血量少于50的时候会喝血
        //队友们会在战士喝血的时候给其加防,如果他已经加防则鼓励他
        //怪物们会在他喝血的时候骂他
        //基类
        public class Person
        {
            public Person(string name, int health, int attack, int defend)
            {
                this.name = name;
                this.health = health;
                this.attack = attack;
                this.defend = defend;
            }
            public string name;
            public int health;
            public int attack;
            public int defend;
            public bool isAddDefend;
        }
        public class Fighter : Person
        {
            public Fighter(string name, int health, int attack, int defend) : base(name, health, attack, defend)
            {
                OnDamage += DamageCheck;
            }
            public event MyDelegate OnDamage;
            public event FighterDelegate OnHealth;
            //受伤
            public void Damage(int attack)
            {
                int damage = attack - defend;
                damage = damage >= 0 ? damage : 1;
                health -= damage;
                OnDamage?.Invoke();
            }
            //攻击
            void Attack(Monster monster)
            {
                monster.Damage(attack);
            }
            //喝血判定
            void DamageCheck()
            {
                if (health < 50)
                {
                    GetHP();
                }
            }
            //喝血
            void GetHP()
            {
                health += 50;
                OnHealth?.Invoke(this);
            }
            //加防
            public void GetDefend(Fighter fighter)
            {
                if (!fighter.isAddDefend)
                {
                    fighter.defend += 100;
                    fighter.isAddDefend = true;
                }
                else
                {
                    Console.WriteLine("{0}加油,我相信,你能行", name);
                }
            }
            //打印数据
            public override string ToString()
            {
                return string.Format("战士{0}: 血量[{1}],攻击[{2}],防御[{3}]", name, health, attack, defend);
            }
        }
        public class Monster : Person
        {
            public Monster(string name, int health, int attack, int defend) : base(name, health, attack, defend)
            {
            }
            //受伤
            public void Damage(int attack)
            {
                int damage = attack - defend;
                damage = damage >= 0 ? damage : 1;
                health -= damage;
            }
            //攻击
            public void Attack(Fighter fighter)
            {
                fighter.Damage(attack);
            }
            //吼叫
            public void Cry(Fighter fighter)
            {
                Console.WriteLine("{0},你的血量是{1},真是不要脸,打哥布林还喝血", fighter.name, fighter.health);
            }
            //打印数据
            public override string ToString()
            {
                return string.Format("怪物{0}:血量[{1}],攻击[{2}],防御[{3}]", name, health, attack, defend);
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
                //玩家创建
                Fighter fighter = new Fighter("小明", 100, 20, 0);
                Console.WriteLine(fighter);
                //队友构建,并把加防注册到到战士身上
                Fighter[] fighters = new Fighter[10];
                for (int i = 0; i < fighters.Length; i++)
                {
                    fighters[i] = new Fighter("队友", 0, 0, 0);
                    fighter.OnHealth += fighters[i].GetDefend;
                }
                //怪物创建
                Random roll = new Random();
                Monster[] monsters = new Monster[10];
                for (int i = 0; i < monsters.Length; i++)
                {
                    monsters[i] = new Monster("" + (i + 1) + "", roll.Next(10, 21), roll.Next(10, 15), roll.Next(5, 11));
                    fighter.OnHealth += monsters[i].Cry;
                }
                //游戏流程
                foreach (var item in monsters)
                {
                    Console.WriteLine(item);
                    item.Attack(fighter);
                    Console.ReadKey(true);
                    Console.WriteLine(fighter);
                }
            }
        }
    }
  • 相关阅读:
    luogu1803 凌乱的yyy / 线段覆盖
    luogu1051 谁拿了最多奖学金
    luogu1208 [USACO1.3]混合牛奶 Mixing Milk
    luogu1090合并果子
    Lab 1 : Part 1 exercise 2
    动态规划(DP)笔记(三):常见普通题型
    leetcode 213. 打家劫舍II: 动态规划(c++)
    动态规划(DP)笔记(二): 序列型及简单例题
    Lab1: Booting a PC
    动态规划(DP)笔记(一): 简介
  • 原文地址:https://www.cnblogs.com/vuciao/p/10362524.html
Copyright © 2020-2023  润新知