C#学习笔记一 委托、事件
创始人
2024-03-28 07:51:06
0

C# 委托、事件

在这里插入图片描述

1、Action委托、Func委托

namespace DelegateExample
{class Program{static void main(string[] args){Calculator calculator=new Calculator();//Action委托Action Cal=new Action(calculator.Report);//直接调用函数Calculator.Report();//通过委托调用函数Cal.Invoke();//简便写法Cal();//Func委托int a=100,b=200,c=0;Func func1=new Func(Calculator.Add); //尖括号中为<参数1,参数2,返回值>Func func2=new Func(Calculator.Sub);//利用委托调用函数c=func1.Invoke(a,b);//简便写法 c=func1(a,b)Console.WriteLine(c);c=func2.Invoke(a,b);//简便写法 c=func1(a,b)Console.WriteLine(c);}}class Calculator{public void  Report(){console.WriteLine("123");}public int Add(int a,int b){int result=a+b;return result;}public int Sub(int a,int b){int result=a-b;return result;}}}

2、自定义委托

在这里插入图片描述

避免写错地方结果声明成嵌套类型:

​ 一般委托的声明在命名空间内,和Program类同级,如果声明在Program类中,会声明成为嵌套类 类型。

namespace DelegateExample
{//自定义委托声明格式public delegate double Cal(double x,double y);class Program{static void main(string[] args){Calculator calculator=new Calculator();Cal cal1=new Cal(calculator.Add);Cal cal2=new Cal(calculator.Sub);Cal cal3=new Cal(calculator.Mul);Cal cal4=new Cal(calculator.Div);double a=200,b=100,c=0;c=cal1.invoke(a,b);Console.WriteLine(c);c=cal2.invoke(a,b);Console.WriteLine(c);c=cal3.invoke(a,b);Console.WriteLine(c);c=cal4.invoke(a,b);Console.WriteLine(c);}   }class Calculator{public double Add(double a,double b){return a+b;}public double Sub(double a,double b){return a-b;}public double Mul(double a,double b){return a*b;}public double Div(double a,double b){return a/b;}}}

3、委托的一般使用

在这里插入图片描述

3.1 模板方法

using System;
using System.Collections.Generic;namespace DelegateExample
{class Program{static void Main(string[] args){WrapFactory wrapFactory = new WrapFactory();ProductFactory productFactory = new ProductFactory();Func func1 = new Func(productFactory.MakePizza);Func func2 = new Func(productFactory.MakeToyCar);Box box1 = wrapFactory.WrapProduct(func1);Box box2 = wrapFactory.WrapProduct(func2);Console.WriteLine(box1.Product.Name);Console.WriteLine(box2.Product.Name);Console.ReadKey();}}class Product{public string Name{ get; set; }}class Box{public Product Product { get; set; }}class WrapFactory{public Box WrapProduct(Func getProduct){Product product = getProduct.Invoke();Box box = new Box();box.Product = product;return box;}}class ProductFactory{public Product MakePizza(){Product product = new Product();product.Name = "Pizza";return product;}public Product MakeToyCar(){Product product = new Product();product.Name = "Toy Car";return product;}}}
//使用模板方法的好处,代码复用性高,只需要扩充ProductFactory类中的方法
//Product类、WrapFactory类,均不用修改

3.2 回调方法

需求:

使用委托的回调方法,在上述代码中实现,若产品价格大于等于50时,打印输出商品信息

using System;
using System.Collections.Generic;namespace DelegateExample
{class Program{static void Main(string[] args){WrapFactory wrapFactory = new WrapFactory();ProductFactory productFactory = new ProductFactory();Func func1 = new Func(productFactory.MakePizza);Func func2 = new Func(productFactory.MakeToyCar);Logger logger = new Logger();Action log = new Action(logger.Log);Box box1 = wrapFactory.WrapProduct(func1,log);Box box2 = wrapFactory.WrapProduct(func2,log);Console.WriteLine(box1.Product.Name);Console.WriteLine(box2.Product.Name);Console.ReadKey();}}class Logger{public void Log(Product product){Console.WriteLine("Product '{0}' created at {1}. Price is {2}.", product.Name, DateTime.UtcNow, product.Price);}}class Product{public string Name{ get; set; }public double Price { get; set; }}class Box{public Product Product { get; set; }}class WrapFactory{public Box WrapProduct(Func getProduct,Action logCallback){Product product = getProduct.Invoke();if (product.Price >= 50){logCallback(product);}Box box = new Box();box.Product = product;return box;}}class ProductFactory{public Product MakePizza(){Product product = new Product();product.Name = "Pizza";product.Price = 20;return product;}public Product MakeToyCar(){Product product = new Product();product.Name = "Toy Car";product.Price = 99;return product;}}}

3.3 委托的高级使用

同步与异步的概念:与中文不同

多播委托

using System;
using System.Collections.Generic;
using System.Threading;
namespace DelegateExample 
{class Program{static void Main(string[] args){Student stu1 = new Student() { ID = 1, PenColor = ConsoleColor.Yellow };Student stu2 = new Student() { ID = 1, PenColor = ConsoleColor.Green };Student stu3 = new Student() { ID = 1, PenColor = ConsoleColor.Red };Action action1 = new Action(stu1.DoHomeWork);Action action2 = new Action(stu2.DoHomeWork);Action action3= new Action(stu3.DoHomeWork);//单播委托/*action1.Invoke();action2.Invoke();action3.Invoke();*///多播委托action1 += action2;action1 += action3;action1.Invoke();Console.ReadKey();}}class Student{public int ID { get; set; }public ConsoleColor PenColor { get; set; }public void DoHomeWork(){for (int i = 0; i < 5; i++){Console.ForegroundColor = this.PenColor;Console.WriteLine("Student {0} doing homework {1} hour(s).", this.ID, i);Thread.Sleep(1000);}}}}

隐式异步调用

​ 首先了解一下同步调用

​ 直接同步调用与间接同步调用

using System;
using System.Collections.Generic;
using System.Threading;
namespace DelegateExample 
{class Program{static void Main(string[] args){Student stu1 = new Student() { ID = 1, PenColor = ConsoleColor.Yellow };Student stu2 = new Student() { ID = 1, PenColor = ConsoleColor.Green };Student stu3 = new Student() { ID = 1, PenColor = ConsoleColor.Red };//直接同步调用/*stu1.DoHomeWork();stu2.DoHomeWork();stu3.DoHomeWork();*///间接同步调用Action action1 = new Action(stu1.DoHomeWork);Action action2 = new Action(stu2.DoHomeWork);Action action3 = new Action(stu3.DoHomeWork);action1.Invoke();action2.Invoke();action3.Invoke();//或者使用多播委托,也是同步调用的//action1+=action2;action1+=action3;action1.Invoke();for (int i = 0; i < 10; i++){Console.ForegroundColor = ConsoleColor.Cyan;Console.WriteLine("Main thread {0}.", i);Thread.Sleep(1000);}Console.ReadKey();}}class Student{public int ID { get; set; }public ConsoleColor PenColor { get; set; }public void DoHomeWork(){for (int i = 0; i < 5; i++){Console.ForegroundColor = this.PenColor;Console.WriteLine("Student {0} doing homework {1} hour(s).", this.ID, i);Thread.Sleep(1000);}}}
}

异步调用

​ 隐式异步调用

using System;
using System.Collections.Generic;
using System.Threading;
namespace DelegateExample 
{class Program{static void Main(string[] args){Student stu1 = new Student() { ID = 1, PenColor = ConsoleColor.Yellow };Student stu2 = new Student() { ID = 1, PenColor = ConsoleColor.Green };Student stu3 = new Student() { ID = 1, PenColor = ConsoleColor.Red };//隐式异步调用Action action1 = new Action(stu1.DoHomeWork);Action action2 = new Action(stu2.DoHomeWork);Action action3 = new Action(stu3.DoHomeWork);action1.BeginInvoke(null,null);action2.BeginInvoke(null, null);action3.BeginInvoke(null, null);for (int i = 0; i < 10; i++){Console.ForegroundColor = ConsoleColor.Cyan;Console.WriteLine("Main thread {0}.", i);Thread.Sleep(1000);}Console.ReadKey();}}class Student{public int ID { get; set; }public ConsoleColor PenColor { get; set; }public void DoHomeWork(){for (int i = 0; i < 5; i++){Console.ForegroundColor = this.PenColor;Console.WriteLine("Student {0} doing homework {1} hour(s).", this.ID, i);Thread.Sleep(1000);}}}}

显式异步调用(古老的方式:使用Thread进行显示异步调用)

using System;
using System.Collections.Generic;
using System.Threading;
namespace DelegateExample 
{class Program{static void Main(string[] args){Student stu1 = new Student() { ID = 1, PenColor = ConsoleColor.Yellow };Student stu2 = new Student() { ID = 1, PenColor = ConsoleColor.Green };Student stu3 = new Student() { ID = 1, PenColor = ConsoleColor.Red };/*            Action action1 = new Action(stu1.DoHomeWork);Action action2 = new Action(stu2.DoHomeWork);Action action3 = new Action(stu3.DoHomeWork);//隐式异步调用action1.BeginInvoke(null,null);action2.BeginInvoke(null, null);action3.BeginInvoke(null, null);*///使用Thread进行显式异步调用Thread thread1 = new Thread(new ThreadStart(stu1.DoHomeWork));Thread thread2 = new Thread(new ThreadStart(stu2.DoHomeWork));Thread thread3 = new Thread(new ThreadStart(stu3.DoHomeWork));thread1.Start();thread2.Start();thread3.Start();for (int i = 0; i < 10; i++){Console.ForegroundColor = ConsoleColor.Cyan;Console.WriteLine("Main thread {0}.", i);Thread.Sleep(1000);}Console.ReadKey();}}class Student{public int ID { get; set; }public ConsoleColor PenColor { get; set; }public void DoHomeWork(){for (int i = 0; i < 5; i++){Console.ForegroundColor = this.PenColor;Console.WriteLine("Student {0} doing homework {1} hour(s).", this.ID, i);Thread.Sleep(1000);}}}
}

显式异步调用更高级的方式:Task,需要引用System.Threading.Tasks命名空间

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace DelegateExample 
{class Program{public static object TTask { get; private set; }static void Main(string[] args){Student stu1 = new Student() { ID = 1, PenColor = ConsoleColor.Yellow };Student stu2 = new Student() { ID = 1, PenColor = ConsoleColor.Green };Student stu3 = new Student() { ID = 1, PenColor = ConsoleColor.Red };/*            Action action1 = new Action(stu1.DoHomeWork);Action action2 = new Action(stu2.DoHomeWork);Action action3 = new Action(stu3.DoHomeWork);//隐式异步调用action1.BeginInvoke(null,null);action2.BeginInvoke(null, null);action3.BeginInvoke(null, null);*///使用Thread进行显式异步调用/*Thread thread1 = new Thread(new ThreadStart(stu1.DoHomeWork));Thread thread2 = new Thread(new ThreadStart(stu2.DoHomeWork));Thread thread3 = new Thread(new ThreadStart(stu3.DoHomeWork));thread1.Start();thread2.Start();thread3.Start();*///更高级的方式,使用Task进行显式异步调用Task task1 = new Task(new Action(stu1.DoHomeWork));Task task2 = new Task(new Action(stu2.DoHomeWork));Task task3 = new Task(new Action(stu3.DoHomeWork));task1.Start();task2.Start();task3.Start();for (int i = 0; i < 10; i++){Console.ForegroundColor = ConsoleColor.Cyan;Console.WriteLine("Main thread {0}.", i);Thread.Sleep(1000);}Console.ReadKey();}}class Student{public int ID { get; set; }public ConsoleColor PenColor { get; set; }public void DoHomeWork(){for (int i = 0; i < 5; i++){Console.ForegroundColor = this.PenColor;Console.WriteLine("Student {0} doing homework {1} hour(s).", this.ID, i);Thread.Sleep(1000);}}}
}

最好用接口代替委托

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Mhj2pXf5-1670512875811)(C:\Users\Wu\AppData\Roaming\Typora\typora-user-images\image-20221208185431055.png)]

用接口代替第一个案例中的委托

using System;
using System.Collections.Generic;namespace DelegateExample
{class Program{static void Main(string[] args){IProductFactory pizzaFactory = new PizzaFactory();IProductFactory toyCarFactory = new ToyCarFactory();WrapFactory wrapFactory = new WrapFactory();Box box1 = wrapFactory.WrapProduct(pizzaFactory);Box box2 = wrapFactory.WrapProduct(toyCarFactory);Console.WriteLine(box1.Product.Name);Console.WriteLine(box2.Product.Name);Console.ReadKey();}}interface IProductFactory{Product Make();}class PizzaFactory : IProductFactory{public Product Make(){Product product = new Product();product.Name = "Pizza";return product;}}class ToyCarFactory : IProductFactory{public Product Make(){Product product = new Product();product.Name = "Toy Car";return product;}}class Product{public string Name { get; set; }public double Price { get; set; }}class Box{public Product Product { get; set; }}class WrapFactory{public Box WrapProduct(IProductFactory productFactory){Product product = productFactory.Make();Box box = new Box();box.Product = product;return box;}}
}

事件

1.初步了解

在这里插入图片描述

在这里插入图片描述
统一称为事件的订阅者

在这里插入图片描述
统一称为事件参数

2.动手操作
在这里插入图片描述

1.事件的简单示例

using System;
using System.Timers;
namespace EventExample
{class Program{static void Main(string[] args){Timer timer = new Timer();//timer为事件的拥有者timer.Interval = 1000;Boy boy = new Boy();//boy为事件的订阅者Girl girl = new Girl();timer.Elapsed += boy.Action;timer.Elapsed += girl.Action;timer.Start();Console.ReadLine();}}class Boy{internal void Action(object sender, ElapsedEventArgs e){Console.WriteLine("Jump!");}}class Girl{internal void Action(object sender, ElapsedEventArgs e){Console.WriteLine("Sing!");}}}
  1. 示例2

在这里插入图片描述

using System;
using System.Windows.Forms;namespace EventExample
{class Program{static void Main(string[] args){Form form = new Form();//form是事件的拥有者Controller controller = new Controller(form);//controller是事件的订阅者form.ShowDialog();}}class Controller{private Form form;public Controller(Form form){if (form != null){this.form = form;this.form.Click += this.FormClicked;//form.Click是事件成员,FromClicked是事件处理器}}private void FormClicked(object sender, EventArgs e){this.form.Text = DateTime.Now.ToString();}}
}

3.示例3
在这里插入图片描述

using System;
using System.Windows.Forms;namespace EventExample
{class Program{static void Main(string[] args){MyForm form = new MyForm();//form事件拥有者form.Click += form.FormClicked;//事件成员form.Click;事件处理器form.FormClicked;//事件订阅者也是form;form.ShowDialog();}}class MyForm : Form{internal void FormClicked(object sender, EventArgs e){this.Text = DateTime.Now.ToString();}}
}

4.示例4

using System;
using System.Windows.Forms;namespace EventExample
{class Program{static void Main(string[] args){MyForm form = new MyForm();form.ShowDialog();}}class MyForm : Form{private TextBox textBox;private Button button;//事件拥有者是实例化的 Form.buttonpublic MyForm(){this.textBox = new TextBox();this.button = new Button();this.Controls.Add(this.button);this.Controls.Add(this.textBox);this.button.Click += ButtonClicked;//button.Click是事件成员,//ButtonClicked是事件处理器//事件订阅者是MyForm的实例}private void ButtonClicked(object sender, EventArgs e){this.textBox.Text = "Hello, World!";}}
}

委托、事件

  • C# 委托、事件
    • 1、Action委托、Func委托
    • 2、自定义委托
    • 3、委托的一般使用
      • 3.1 模板方法
      • 3.2 回调方法
      • 3.3 委托的高级使用
        • 同步与异步的概念:与中文不同
        • 多播委托
        • **隐式异步调用**
        • **异步调用**
      • 最好用接口代替委托
  • 事件

相关内容

热门资讯

【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...