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);
            }
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/ciaowoo/p/10362524.html