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);
}
}
}
}
C#学习笔记(十七):委托、事件、观察者模式、匿名委托和lambert表达式的更多相关文章
- C#委托,事件,匿名委托
作为一个初学者,写下来是当做自己的学习笔记,希望在以后遇到问题的时候能够快速的找到方法 如果能帮助跟我一样的新人是更好不过的了 如果有什么不正确或者可以改进的地方也希望大家能够指出来 ...
- python3.4学习笔记(十七) 网络爬虫使用Beautifulsoup4抓取内容
python3.4学习笔记(十七) 网络爬虫使用Beautifulsoup4抓取内容 Beautiful Soup 是用Python写的一个HTML/XML的解析器,它可以很好的处理不规范标记并生成剖 ...
- iOS学习笔记之触摸事件&UIResponder
iOS学习笔记之触摸事件&UIResponder 触摸事件 与触摸事件相关的四个方法如下: 一根手指或多根手指触摸屏幕 -(void)touchesBegan:(NSSet *)touches ...
- [C#学习教程-委托]001.大道至简之委托(代理),匿名函数,Lambda表达式
引言:此文翻译自CodeProject上的同名文章<C# Delegates,Anonymous Methods, and Lambda Expressions>,在此一起Mark一下,此 ...
- 微信小程序学习笔记二 数据绑定 + 事件绑定
微信小程序学习笔记二 1. 小程序特点概述 没有DOM 组件化开发: 具备特定功能效果的代码集合 体积小, 单个压缩包体积不能大于2M, 否则无法上线 小程序的四个重要的文件 *js *.wxml - ...
- Ext JS学习第十七天 事件机制event(二)
此文仅有继续学习笔记: 昨天说了三种邦定事件的方法,今天说一下自定义事件 假设现在又这样的情景一个自定义的事件 没有用到事件处理的场景 母亲问孩子和不饿-> ...
- C#动态创建两个按钮,btn2复制btn1的Click事件,匿名委托
现在有一个按钮btn1,要动态创建出一个btn2,需要btn2点击时调用btn1的点击. 在delphi中这种操作很简单:btn2.onClick:=btn1.onClick,因为onClick就是个 ...
- 【ALB学习笔记】基于事件触发方式的串行通信接口数据接收案例
基于事件触发方式的串行通信接口数据接收案例 广东职业技术学院 欧浩源 一.案例背景 之前写过一篇<基于多线程方式的串行通信接口数据接收案例>的博文,讨论了采用轮询方式接收串口数据的情况. ...
- AngularJS1.X学习笔记4-内置事件指令及其他
AngularJS为我们定义了一系列事件指令,方便我们对用户的操作作出响应.甚至他还有一个可选模块提供了触摸事件和手势事件的支持,为移动端开发提供了可能.现在开始学习一下AngularJS的事件指令. ...
- python cookbook第三版学习笔记十七:委托属性
我们想在访问实例的属性时能够将其委托到一个内部持有的对象上,这经常用到代理机制上 class A: def spam(self,x): print("class_A: ...
随机推荐
- nodejs(五)同步异步--BLOCKING THE EVENT LOOP
1.BLOCKING THE EVENT LOOP Node and JavaScript runtimes in general are single-threaded event loops. O ...
- sql server低版本到高版本还原,找不到备份集
关键词:sql server低版本到高版本还原 故障问题,图中备份集(红色框线部分)没有数据,无法选择,导致无法还原 解决办法: [1] 低版本的备份到高版本的,用语句可以还原 注意事项: 低版本不一 ...
- android studio 1
1.继承activity类的时候,重写父类 @Override //伪代码 ,代表如果不是重写父类的方法,该地方会报错 protected void onCreate( Bundle savedI ...
- gradle build scan
1:gradle build scan 用于视图审查 构建步骤如下 https://guides.gradle.org/creating-build-scans/?_ga=2.80362963.59 ...
- Andrew Ng-ML-第十六章-异常检测
1.问题动机 图1.飞机发动机检测例子 对飞机引擎的例子,如果选取了两个特征x1热量产生度,x2震动强度.并得到如下的图,如果有一个新的引擎来检测其是否正常,x_test,那么此时如果点落在和其他点正 ...
- Android APP安装后不在桌面显示图标的应用场景举例和实现方法
最近在为公司做一款车联网的产品,由于公司本身擅长于汽车解码器的研发,所以该产品的诊断功能的实现除了使用目前市面上车联网产品中大量使用的OBD协议外,还会使用一些专车专用协议去实现一些特殊的诊断功能,如 ...
- EXTJS4扩展实例:如何使用filter查询treepanel
我们在使用普通的store时,extjs提供了filterBy,filter等多种方法来过滤数据达到查询效果,但在treepanel中的streeStore却没有实现这个查询,于是,就有了这篇文章. ...
- Python基础socket编程
Python 提供了两个基本的 socket 模块. 第一个是 Socket,它提供了标准的 BSD Sockets API. 第二个是 SocketServer, 它提供了服务器中心类,可以简化网络 ...
- html08
1.JQuery 是一个js框架一堆的 js文件 -形成 > 包 - 形成> 工具 - 形成> ->库 -> 框架 是一个轻量级的库 封装了js原生里js css dom ...
- Liferay中request
在liferay中的请求分为renderRequest和actionRequest这两种请求的方式,portletRequest的子类有三个1renderRequest,2EventRequest3C ...