IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C#之委托 -> 正文阅读

[C++知识库]C#之委托

关于委托的学习笔记

  1. 委托是一种类,类是数据类型,所以委托也是数据类型
//Action是一种类
Type t = typeof(Action);
Console.Write(t.IsClass);
  1. 委托是函数指针的升级版
    函数指针(C++):
#include <stdio.h>

//一个指向有两个参数和一个返回值的函数的指针
//这个指针只可以指向有两个int类型参数和一个int类型返回值的函数
//typedef 的作用在于,将这个指针定义为一种数据类型
//Calc 是给这个函数指针起的名称
typedef int(*Calc)(int a,int b);

//函数(方法)
int Add(int a,int b){
	int result = a + b;
	return result;
}

//主函数
int main(){
	int x = 100;
	int y = 100;
	int z = 0;

	//声明函数指针类型的变量
	//将Add函数的地址赋值给这个变量
	Calc calc = &Add;
	
	//1. 直接调用Add函数
	z = Add(x,y);
	printf("%d+%d=%d",x,y,z);

	//2. 通过函数指针,间接调用Add函数
	z = calc(x,y);
	printf("%d+%d=%d",x,y,z);
	
	//使控制台等待输入回车,便于观察控制台输出的结果
	system("pause");
}
  1. C#中比较常见的两种委托类型
    3.1 Action
    一般用于指向没有返回值的方法
class Student
{
	static void Main(string[] args)
	{
		//声明一个Action的变量,并创建一个实例
		//这个实例指向的是一个没有参数和返回值的方法PrintInf
		Action act = new Action(PrintInf);
		
		//1. 直接调用方法
		PrintInf();

		//2. 使用委托间接调用方法
		act.Invork();
		//简便写法,模仿函数指针的书写格式
		act();
	}
	
	public void PrintInf()
	{
		Console.WriteLine("My Name is Wednesday.");
	}
}

3.2 Func
一般用于指向有返回值的方法

class Student
{
	static void Main(string[] args)
	{
		//声明一个Func的变量,并创建一个实例
		//这个实例指向的是一个具有两个int类型的参数和int类型返回值的方法Add
		//前面两个int代表了方法具有的参数
		//第三个int代表这个方法的返回值类型
		Func<int,int,int> func = new Func<int,int,int>(Add);  
		
		int i = 100int j = 100int z = 0;
		//1. 直接调用方法
		z = Add(i,j);

		//2. 使用委托间接调用方法
		z = func.Invork(i,j);
		//简便写法,模仿函数指针的书写格式
		z = func(i,j);
	}
	
	public int Add(int x,int y)
	{
		return  x + y;
	}
}
  1. 自定义委托
    委托是一种类,那么在自定义委托时,要把定义语句写在命名空间体内,如果写在类中,就变成了这个类的嵌套类了
namespace Study
{
	//自定义一个委托,需要使用关键字:delegate
	//这个委托指向一个具有两个int类型参数、返回值为int类型的方法
	public delegate int Calc(int,int);

	class Student
	{
		static void Main(string[] args)
		{
			//创建委托的变量和实例
			//在创建实例时,这个实例的构造函数要求指向一个具有两个int类型参数、返回值为int类型的方法
			Calc calc = new Calc(Add);
			
			int i = 100;
			int j = 100;
			int z = 0;
			
			//1. 直接调用Add方法
			z = Add(i,j);
			
			//2. 间接调用Add方法
			z = calc.Invork(i,j);
			//简便写法,模仿函数指针的书写格式
			z = calc(i,j);
		}
		
		int Add(int x, int y)
		{
			return x + y;
		}
	}
}
  1. 委托的一般使用
    5.1 模板方法
    · 在方法中,根据委托所指向的方法返回的数据,来进行记算。
    · 委托有返回值
static void Main(string[] args)
{
	int x = 100;
	int y = 100;
	int z = 0;
	
	Func<int,int,int> act = new Func<int,int,int>(Add);
	z = 100 + act.Invork(x,y);
}

int GetNum(int x, int y)
{
	return x + y;
}

5.2 回调方法
· 由主调方法决定是否调用被调方法
· 委托无返回值

static void Main(string[] args)
{
	int x = 2;
	int y = 3;

	Action<int> act = new Action<int>(PrintInf);
	
	if(x % 2 != 0)
		act.Invork(x);
	if(y % 2 != 0)
		act.Invork(y);
}

void PrintInf(int x)
{
	Console.WriteLine(x + "是一个单数.");
}
  1. 委托的高级使用
    6.1 多播委托:一个委托指向多个方法
static void Main(string[] args)
{
	Action act1 = new Action(PrintInf);
	Action act2 = new Action(PrintInf);
	Action act2 = new Action(PrintInf);

	//将act2加到act1上;
	act1 += act2;
	//将act3加到act1上;
	act1 += act3;

	//只执行act1,这三个委托都会依次执行
	act1.Invork();
}

void PrintInf()
{
	Console.WriteLine("My name is Wednesday.");
}

6.2 隐式异步调用
多播委托的例子为同步调用,异步调用则是指多线程并行调用

· 使用多线程显示异步调用

static void Main(string[] args)
{
	Thread thread1 = new Thread(new ThreadStart(PrintInf));
	Thread thread2 = new Thread(new ThreadStart(PrintInf));
	Thread thread3 = new Thread(new ThreadStart(PrintInf));
	thread1.Start();
	thread2.Start();
	thread3.Start();
}

void PrintInf()
{
    for (int i = 0; i < 10; i++)
    {
        Console.WriteLine("My name is Wednesday,I'm {0} years old", i);
        Thread.Sleep(1000);
    }
}

运行结果:每条线程并发执行
在这里插入图片描述
· 使用委托隐式异步调用:

static void Main(string[] args)
{
	Action act1 = new Action(PrintInf);
	Action act2 = new Action(PrintInf);
	Action act3 = new Action(PrintInf);
	act1.BeginInvoke(null,null);
	act2.BeginInvoke(null,null);
	act3.BeginInvoke(null,null);
}

void PrintInf()
{
    for (int i = 0; i < 10; i++)
    {
        Console.WriteLine("My name is Wednesday,I'm {0} years old", i);
        Thread.Sleep(1000);
    }
}

运行结果:
在这里插入图片描述

使用委托隐式异步调用,和使用多线程显示异步调用,结果都是一样的,那么隐式和显示的区别是什么?
这里说的隐式异步调用全称应该是:多线程隐式异步调用
也就是说,通过委托的BeginInvoke()方法,我们实现了多线程异步调用,而实现多线程异步调用这一步骤的具体操作,是由编译器来实现的,并不是我们手动的创建多线程去实现的,所以称之为"隐式异步调用"。而多线程显示异步调用,也就是由我们直接手动创建多线程异步调用。

  1. 前面说到,我们C#的委托是C语言的函数指针的升级版,Java语言考虑安全问题,并不具有"指针"这一功能,那么在Java中,怎么实现委托的功能呢。
    那就是interface,Java完全使用接口代替了委托,所以在C#中,我们也可以在不适合使用委托时,使用接口来代替委托。
    7.1 委托的一些缺点:
    · 高耦合,委托属于方法级别的耦合;
    · 使代码可读性下降,增加debug难度;
    · 使用不当可能造成内存泄漏,让程序性能下降:
    当委托里封装着一个类的方法时,即使没有引用变量引用这个类,在内存中也会给这个类分配内容空间,从而造成内存泄漏,以及程序性能下降;
    · 等;
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-11 16:14:52  更:2022-05-11 16:16:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 18:25:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码