【C#】委托

news2024/11/19 8:35:51

文章目录

  • 委托
  • 自定义委托
  • 模板方法(工厂模式
  • 回调(callback)函数(观察者模式
  • 多播(multicast)委托
  • 委托的高级使用
  • 使用接口 重构 模板方法代码
  • 注意
  • 参考


委托

委托(delegate)是一种类型,定义了一种方法签名,因此可以将方法作为参数进行传递。
委托类似于 C++ 中的函数指针,但比函数指针更加安全和灵活。
使用委托,可以实现事件处理、回调函数等功能。
建议:使用接口取代委托

  • Action
    • 无参无返回
  • Func
    • 有参有返回
        Calaculator calaculator = new Calaculator();
        
        // Action
        new Action(calaculator.Report).Invoke();
        
        // Func
		Func<int, int, int> func1 = new Func<int, int, int>(calaculator.Add);
		Func<int, int, int> func2 = new Func<int, int, int>(calaculator.Sub);
		
		int x = 100;
		int y = 200;
		int z = 0;

		// 可以省略invoke
		z = func1(x, y);
		Console.WriteLine(z);

		z = func2.Invoke(x, y);
		Console.WriteLine(z);

class Calaculator {
    public void Report()
    {
        Console.WriteLine("i have 3 methods");
    }

    public int Add(int a, int b)
    {
        return a + b;
    }

    public int Sub(int a, int b)
    {
        return a - b;
    }
}

自定义委托

// 与类平级,放到类中属于嵌套
public delegate double Calc(double x,double y);
internal class Program
{
    static void Main(string[] args)
    {
        Calaculator calaculator = new Calaculator();
        Calc calc1 = new Calc(calaculator.Add1);
        Calc calc2 = new Calc(calaculator.Mul);

        double x = 100;
        double y = 100;
        double z = 0;
        z = calc1.Invoke(x, y);
        Console.WriteLine(z);
        z = calc2.Invoke(x, y);
        Console.WriteLine(z);
	}
}

模板方法(工厂模式

”借用“指定的外部方法来产生结果 , 提高对代码的复用
ProductFactory() 只需要扩展这个方法,其他方法都不用动

    static void Main(string[] args)
    {
        ProductFactory productFactory = new ProductFactory();
        WrapFactory wrapFactory = new WrapFactory();

        Func<Product> func1 = new Func<Product>(productFactory.MakeToy);
        Func<Product> func2 = new Func<Product>(productFactory.MakePizza);

        Box box1 = wrapFactory.WrapProduct(func1);
        Box box2 = wrapFactory.WrapProduct(func2);

        Console.WriteLine(box1.Product.Name);
        Console.WriteLine(box2.Product.Name);
    }
}

class Product() { 
    public string Name { get; set; }
}

class Box() { 
    public Product Product { get; set; }
}

class WrapFactory {
    public Box WrapProduct(Func<Product> getProduct) {
        Box box = new Box();
        // invoke 执行拿到产品(不用管是什么产品
        Product product = getProduct.Invoke();
        box.Product = product;
        return box;
    }
}

class ProductFactory() {
    public Product MakePizza() {
        Product product = new Product();
        product.Name = "Pizza";
        return product;
    }
    public Product MakeToy() {
        Product product = new Product();
        product.Name = "Toy";
        return product;
    }
}

回调(callback)函数(观察者模式

调用指定的外部方法
在模板方法基础上添加

internal class Program
{
    static void Main(string[] args)
    {
        ProductFactory productFactory = new ProductFactory();
        WrapFactory wrapFactory = new WrapFactory();

        Func<Product> func1 = new Func<Product>(productFactory.MakeToy);
        Func<Product> func2 = new Func<Product>(productFactory.MakePizza);

        Logger logger = new Logger();
        Action<Product> action = new Action<Product>(logger.Log);

        Box box1 = wrapFactory.WrapProduct(func1,action);
        Box box2 = wrapFactory.WrapProduct(func2,action);

        Console.WriteLine(box1.Product.Name);
        Console.WriteLine(box2.Product.Name);
    }
}

class Logger {
    public void Log(Product product) {
        //DateTime.UtcNow 无时区时间 ; DateTime.Now 有时区
        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<Product> getProduct,Action<Product> logCallback) {
        Box box = new Box();
        Product product = getProduct.Invoke();

        // 回调函数:触发某种条件就自动执行
        if (product.Price >= 50) {
            logCallback(product);
        }

        box.Product = product;
        return box;
    }
}

class ProductFactory() {
    public Product MakePizza() {
        Product product = new Product();
        product.Name = "Pizza";
        product.Price = 12;
        return product;
    }
    public Product MakeToy() {
        Product product = new Product();
        product.Name = "Toy";
        product.Price=120;
        return product;
    }
}

多播(multicast)委托

在这里插入图片描述
在这里插入图片描述

委托的高级使用

1

使用接口 重构 模板方法代码

直接用接口,不使用委托。

方法形参为接口,类继承接口,new不同的类传进同个方法

internal class Program
{
    static void Main(string[] args)
    {
        WrapFactory wrapFactory = new WrapFactory();

        Logger logger = new Logger();
        Action<Product> action = new Action<Product>(logger.Log);

        Box box1 = wrapFactory.WrapProduct(new PizzaFactory());
        Box box2 = wrapFactory.WrapProduct(new ToyCarFactory());

        Console.WriteLine(box1.Product.Name);
        Console.WriteLine(box2.Product.Name);
    }
}

interface IProductFactory {
    Product Make();
}

class PizzaFactory : IProductFactory
{
    public Product Make()
    {
        Product product = new Product();
        product.Name = "Pizza";
        product.Price = 12;
        return product;
    }
}

class ToyCarFactory : IProductFactory
{
    public Product Make()
    {
        Product product = new Product();
        product.Name = "Toy";
        product.Price = 120;
        return product;
    }
}
class WrapFactory {
    public Box WrapProduct(IProductFactory productFactory) {
        Box box = new Box();
        Product product = productFactory.Make();
        box.Product = product;
        return box;
    }
}
}

注意

委托:
1

参考

刘铁猛——C#

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1707720.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

汇编:字符串的输出

在16位汇编程序中&#xff0c;可以使用DOS中断21h的功能号09h来打印字符串&#xff1b;下面是一个简单的示例程序&#xff0c;演示了如何在16位汇编程序中打印字符串&#xff1a; assume cs:code,ds:data ​ data segmentszBuffer db 0dh,0ah,HelloWorld$ //定义字符串 data …

马斯克xAI融资60亿美元,宣布打造世界第一超算中心,10万张H100GPU

昨天&#xff0c;埃隆马斯克的xAI初创公司宣布获得60亿美元的巨额融资&#xff0c;主要用于打造一台巨大的超级计算机&#xff0c;马斯克称之为“超级计算工厂”。 从创立OpenAI到如今的xAI&#xff0c;技术和算力的发展历经了几个时代&#xff0c;但似乎马斯克的吸金能力一直…

MySQL中Undo-log是什么?有什么作用?

2.6.1. Undo-log撤销日志 Undo即撤销的意思&#xff0c;通常也称为回滚日志&#xff0c;用来给MySQL撤销SQL操作的。 当一条写入类型的SQL执行时&#xff0c;都会记录Undo-log日志&#xff0c;Undo-log并不存在单独的日志文件&#xff0c;InnoDB默认是将Undo-log存储在xx.ibd…

C++代码使用ClangCL编译注意事项

遇到cmake指定模板类工程使用msvc的clang编译器编译代码&#xff0c;代码变量出现与预期不符的问题&#xff1b; 如下&#xff1a; clangcl将实现放到头文件里则不会出现这样的情况&#xff1b; 最后按照pcl的模板类写法则解决这个问题&#xff1b;

【从零开始学习RabbitMQ | 第二篇】如何确保MQ的可靠性和消费者可靠性

目录 前言&#xff1a; MQ可靠性&#xff1a; 数据持久化&#xff1a; Lazy Queue&#xff1a; 消费者可靠性&#xff1a; 消费者确认机制&#xff1a; 消费失败处理&#xff1a; MQ保证幂等性&#xff1a; 方法一&#xff1a; 总结&#xff1a; 前言&#xff1a; …

windows帐户自动被锁定解决方法

处理方法方法一&#xff1a; 运行-gpedit.msc&#xff0c;打开组策略&#xff0c; 处理方法方法二&#xff1a; 运行-gpedit.msc&#xff0c;打开组策略&#xff0c; 在本地组策略编辑器页面中&#xff0c;选择计算机配置 > Windows设置 > 安全设置 > 账户策略 > 账…

Linux防火墙(以iptables为例)

目录 Linux配置防火墙1. 引言2. 什么是防火墙3. Linux中的防火墙3.1 iptablesiptables命令参数常用方式&#xff1a;3.1.1 安装iptables3.1.2 配置iptables规则3.1.3 示例一&#xff1a;使用iptables配置防火墙规则4. iptables执行过程 Linux配置防火墙 1. 引言 在互联网时代&…

NIUSHOP 开源商城 V6 开源版(商城+分销+VIPCard+上门服务)前端技术探索与实践

摘要&#xff1a; 本文深入探讨了NIUSHOP V6开源商城前端技术的选型、实现与设计理念。NIUSHOP V6作为一款优秀的企业级商城系统&#xff0c;其前端采用了Vite、TypeScript、Vue3及ElementPlus等最新技术栈&#xff0c;为开发者提供了高效、灵活的开发体验。本文将从技术选型、…

某有赞滑块验证码

⚠️前言⚠️ 本文仅用于学术交流。 学习探讨逆向知识&#xff0c;欢迎私信共享学习心得。 如有侵权&#xff0c;联系博主删除。 请勿商用&#xff0c;否则后果自负。 网址 aHR0cHM6Ly9wYXNzcG9ydC55b3V6YW4uY29tL2xvZ2luL3Bhc3N3b3Jk 1. 首先来分析一下参数 1_1. get-beh…

宝塔下应该用 Memcached 还是 Redis?

明月最近在跟几个使用宝塔面板的客户运维的时候发现不少站长不知道如何选择 Memcached 和 Redis&#xff0c;甚至都说不清楚 Memcached 或者 Redis 具体是用来干啥的&#xff1f;甚至还碰到过一个站长 Memcached 和 Redis 都安装了&#xff0c;但一个都没有用&#xff0c;就那么…

vscode远程登录阿里云服务器【使用密钥方式--后期无需再进行密码登录】【外包需要密码】

1&#xff1a;windows主机上生成【私钥】【公钥】 1.1生成公钥时不设置额外密码 1.2生成公钥时设置额外密码【给外包人员使用的方法】 2&#xff1a;在linux服务器中添加【公钥】 3&#xff1a;本地vscode连接linux服务器的配置 操作流程如下 1.1本地终端中【生成免密登录…

python练习题-反转一个只有三位数的整数

【问题描述】&#xff1a;反转一个只有三位数的整数 [示例]&#xff1a;123 321 完整代码如下&#xff1a; nint(input()) if n<100 or n>999: print("请输入三位数&#xff01;") else: gen%10 shin//10%10 bain//100 m100*ge10*shibai…

Pytorch入门需要达到的效果

会搭建深度学习环境和依赖包安装 使用Anaconda创建环境、在pytorch官网安装pytorch、安装依赖包 会使用常见操作&#xff0c;例如matmul&#xff0c;sigmoid&#xff0c;softmax&#xff0c;relu&#xff0c;linear matmul操作见文章torch.matmul()的用法 sigmoid&#xff0…

【算法】位运算算法——判断字符是否唯一

题解&#xff1a;判断字符是否唯一(位运算算法) 目录 1.题目2.题解3.位图参考代码4.细节5.总结 1.题目 题目链接&#xff1a;LINK 2.题解 题解有两种方法&#xff0c; 一是做一个哈希数组&#xff0c;去查重&#xff1b; 二是直接用一个变量每一位来对应表示是否有这个字母…

Linux主机连接腾讯云服务器详细配置

硬件条件 当然你要先有一个云服务器&#xff0c;腾讯云比阿里云便宜一点&#xff0c;所以就用腾讯云了 问了师兄买这个98的就行&#xff0c;选择CentOS&#xff0c;不要选Ubuntu&#xff0c;因为 嗯&#xff0c;大概就是这样 编程测试 云服务器当然是作为服务端 server.cpp…

LabVIEW高低温试验箱控制系统

要实现LabVIEW高低温试验箱控制系统&#xff0c;需要进行硬件配置、软件设计和系统集成&#xff0c;确保LabVIEW能够有效地监控和控制试验箱的温度。以下是详细说明&#xff1a; 硬件配置 选择合适的试验箱&#xff1a; 确定高低温试验箱的型号和品牌。 确认试验箱是否支持外…

SpringBoot 返回值 i18n 自动处理

定义基础通用类 首先定义一波错误码&#xff1a;ResultCode Getter AllArgsConstructor public enum ResultCode {SUCCESS(200, "请求成功", "request.success"),Fail(400, "请求失败", "request.failed"),PASSWORD_NOT_MATCH(1000…

保护“第二生命线”,科技守护颈椎健康

脊柱支撑着人体重量&#xff0c;汇集着众多血管神经&#xff0c;素有“人体第二生命线”之称。在如今快节奏的时代&#xff0c;人们生活方式也在发生着变化&#xff0c;长期低头看手机、伏案久坐等不良生活习惯引发脊柱健康问题&#xff0c;且呈现年轻化趋势。目前&#xff0c;…

2024.05.22学习记录

1、面经复习&#xff1a; Vue组件通讯、vuex、js严格模式、options请求、vue3 Setup 语法糖、React hook 2、代码随想录刷题&#xff1a;动态规划 3、rosebush组件库 完成Alert和Alert测试 Menu组件初步开发

基于单片机的自行车里程监测系统的设计

摘 要 &#xff1a;本设计是一种基于单片机的自行车里程监测系统&#xff0c;采用 STC89C52RC 单片机为核心处理芯片&#xff0c;液晶显示器使用 LCD1602 &#xff0c; 速度测量使用霍尔传感器&#xff0c;温度传感器使用 DS18B20 &#xff0c;时间由时钟芯片 DS1302 进行…