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: ...
随机推荐
- HTTP上传大文件的注意点
使用HttpWebRequest上传大文件时,服务端配置中需要进行以下节点配置: <system.web> <compilation debug="true" t ...
- Bug笔记:Google Map第一次缩放位置偏移
这是个让人蛋疼的bug,认真查看Google maps API文档的童鞋们一定不会碰到. 我的同事为项目写了个针对map这块的jQuery plugin,然后在项目测试中发现,刚加载完页面时,直接点击 ...
- js-jquery-对象与JSON字符串互相转换
1:jQuery插件支持的转换方式 代码如下: String→Object$.parseJSON( jsonstr ); //jQuery.parseJSON(jsonstr),可以将json字符串转 ...
- [py]彻底细究web框架的wsgi+逻辑处理模块
wsgi逻辑结构初探 参考: 这里图很精彩,wsgi写的不错 web框架 = wsgi+逻辑处理app 接收请求,返回对应的内容 python wsgiref实现了wsgi规范. from wsgir ...
- [py][mx]xadmin注册切换主题功能和网站名称修改
注册主题 这里将基础的设置放到users模块 users/adminx.py from xadmin import views class BaseSetting(object): enable_th ...
- [LeetCode] 172. Factorial Trailing Zeroes_Easy tag: Math
Given an integer n, return the number of trailing zeroes in n!. Example 1: Input: 3 Output: 0 Explan ...
- Logistic Regression Using Gradient Descent -- Binary Classification 代码实现
1. 原理 Cost function Theta 2. Python # -*- coding:utf8 -*- import numpy as np import matplotlib.pyplo ...
- Js中split()方法的正确使用
通过 js 获取 QueryString (location.search部分) 参数很常见,网上代码也满天飞.不过现在的框架,基本上都通过路由伪静态了,把以前的 QueryString 变成了pat ...
- HDU 5059 Help him(简单模拟题)
http://acm.hdu.edu.cn/showproblem.php?pid=5059 题目大意: 给定一个字符串,如果这个字符串是一个整数,并且这个整数在[a,b]的范围之内(包括a,b),那 ...
- 187. Repeated DNA Sequences(建立词典,遍历一遍 o(n))
All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: "ACG ...