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

时间:2023-03-08 17:30:53

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

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

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

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

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

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

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

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(, );
Console.WriteLine();
//注册
//如果我们将一个函数注册到委托
//相当于将函数注册到其委托列表
//这个委托被调用时,将调用到这个注册函数
//注册只需要函数(方法)名,不需要传参
myDelegate += Min;//用的比较多
myDelegate += Min;
myDelegate += Min;
myDelegate(, );
Console.WriteLine();
myDelegate += Max;
myDelegate += Max;
myDelegate += Min;
//myDelegate = Max;
myDelegate(, );
Console.WriteLine();
//注销
//注册就是将一个函数从委托的委托列表中移除
//仅移除最后一个注册的对应函数
//如果委托列表中没有对应的函数不会报错
myDelegate -= Max;
myDelegate(, );
Console.WriteLine();
//调用
//委托会将其 委托列表 中所有的函数按顺序执行
//通过委托我们只能取得最后的执行的函数的返回值
//委托调用时确定其参数,虽然委托中有多个函数,但只能使用一份参数
//委托可以通过 变量名(参数)调用,变量名.Invoke(参数)
Console.WriteLine(myDelegate(, ));
myDelegate.Invoke(, );
//作为参数的应用
//委托可以做为另一个函数的参数使用
//当一个函数使用了委托参数时
//当其被调用时,我们可以直接放入一个对应委托,或者直接放入一个与委托同参同返回的函数参数
}
//如果一个函数和委托的约束的签名一致
//我们就可以把这个函数赋值或注册到委托
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 = { , , , , , , , , , }; //一般方法
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 = ; i < array.Length; i++)
{
//内层循环Length-1-i(外层循环的当前次数)
for (int j = ; j < array.Length - - i; j++)
{
//如果条件(大)达成,交换位置
if (array[j] > array[j + ])
{
int temp = array[j];
array[j] = array[j + ];
array[j + ] = temp;
}
}
}
}
static void SortMin(int[] array)
{
//外层循环Length-1次
for (int i = ; i < array.Length; i++)
{
//内层循环Length-1-i(外层循环的当前次数)
for (int j = ; j < array.Length - - i; j++)
{
//如果条件(小)达成,交换位置
if (array[j] < array[j + ])
{
int temp = array[j];
array[j] = array[j + ];
array[j + ] = temp;
}
}
}
}
static void Sort(int[] array, MyDelegate condition)
{
//外层循环Length-1次
for (int i = ; i < array.Length; i++)
{
//内层循环Length-1-i(外层循环的当前次数)
for (int j = ; j < array.Length - - i; j++)
{
//如果条件(大)达成,交换位置
if (condition(array[j], array[j + ]))
{
int temp = array[j];
array[j] = array[j + ];
array[j + ] = 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 = { , , , , , , , , , };
//匿名委托
//匿名委托只能作为委托的值被使用
//缺陷
//匿名委托可读性差,建议匿名委托语句行数不宜过多,一句最佳
//匿名委托不可复用(违背封装原则)
//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 = ; i < array.Length; i++)
{
//内层循环Length-1-i(外层循环的当前次数)
for (int j = ; j < array.Length - - i; j++)
{
//如果条件(大)达成,交换位置
if (condition(array[j], array[j + ]))
{
int temp = array[j];
array[j] = array[j + ];
array[j + ] = 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 >= ? damage : ;
health -= damage;
OnDamage?.Invoke();
}
//攻击
void Attack(Monster monster)
{
monster.Damage(attack);
}
//喝血判定
void DamageCheck()
{
if (health < )
{
GetHP();
}
}
//喝血
void GetHP()
{
health += ;
OnHealth?.Invoke(this);
}
//加防
public void GetDefend(Fighter fighter)
{
if (!fighter.isAddDefend)
{
fighter.defend += ;
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 >= ? damage : ;
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("小明", , , );
Console.WriteLine(fighter);
//队友构建,并把加防注册到到战士身上
Fighter[] fighters = new Fighter[];
for (int i = ; i < fighters.Length; i++)
{
fighters[i] = new Fighter("队友", , , );
fighter.OnHealth += fighters[i].GetDefend;
}
//怪物创建
Random roll = new Random();
Monster[] monsters = new Monster[];
for (int i = ; i < monsters.Length; i++)
{
monsters[i] = new Monster("" + (i + ) + "号", roll.Next(, ), roll.Next(, ), roll.Next(, ));
fighter.OnHealth += monsters[i].Cry;
}
//游戏流程
foreach (var item in monsters)
{
Console.WriteLine(item);
item.Attack(fighter);
Console.ReadKey(true);
Console.WriteLine(fighter);
}
}
}
}