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