C#——委托(1)
什么是委托?
还记得C/C++语言里的函数指针吗?委托就是他的”升级版“。
先看一个简单的小程序:
# include<stdio.h> typedef int(*Calc)(int a, int b);//使用typedef把他定义成一种数据类型 int Add(int a,int b)
{
int result = a + b;
return result;
} int main(void)
{
int x = ;
int y = ;
int z = ; z = Add(x,y);//直接调用
printf("%d+%d=%d\n",x,y,z); Calc cFun = &Add;//间接调用
z = cFun(x, y);
printf("%d+%d=%d\n", x, y, z); return ;
}
直接调用和间接调用他们的运行结果是一样的
变量和函数到底是啥?
变量(代表数据)是以变量名对应的内存地址为起点的一段内存中所存储的值
函数(代表算法)是以函数名对应的内存地址为起点的一段内存中所存储的一组机器语言指令
知道了啥是变量和函数,那就来看看啥是 直接调用和间接调用
直接调用:通过函数名来调用函数,CPU通过函数名直接获得函数所在地址并开始执行,执行完函数后CPU返回调用者那里继续往下执行
间接调用:通过函数指针来调用函数,CPU通过读取函数指针存储的值(函数名所对应的地址)获得函数所在地址并开始执行,最终返回调用者那里继续往下执行
下面我们就看看委托是个什么东西
namespace DelegateExample_Action_
{
class Program
{
static void Main(string[] args)
{
Calculator calculator = new Calculator();
Action action = new Action(calculator.Report);
action.Invoke();//间接引用
/*
还可以这么写
action();
*/
calculator.Report();//直接引用
//运行结果完全一样
}
} class Calculator
{
public void Report()
{
Console.WriteLine("I have three methods.");
}
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;
}
}
}
IDE提示到,你要往里面放一个返回值为void类型,参数列表为空的一个方法,那么在Calculator类里符合的就是Report方法,所以我们就把Report方法放了进去
运行结果:
第一行是我们直接调用时打印出来的语句,第二行是我们用Action委托打印出来的语句
如果要调用Add或者Sub方法,我们选择使用Func委托:
namespace DelegateExample_Func_
{
class Program
{
static void Main(string[] args)
{
Calculator calculator = new Calculator(); Func<int, int, int> Func1 = new Func<int, int, int>(calculator.Add);
Func<int, int, int> Func2 = new Func<int, int, int>(calculator.Sub);
int x = ;
int y = ;
int z = ;
z = Func1.Invoke(x, y);
Console.WriteLine(z);
z = Func2.Invoke(x, y);
Console.WriteLine(z);
}
} class Calculator
{
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;
}
}
}
在打尖括号时,IDE提示我们他有17个重载,通过下翻会发现,它会增加参数的个数(最后的那个是返回值类型),我们要用他来引用Add和Sub方法,而这两个方法有两个参数,所以我们就选了图片里的那种情况,因为两个参数是int类型,所以返回的结果也一定是int类型 所以就用 Func<int,int,int>(Calculator.Add); (尖括号里前两个是参数类型,最后一个是返回值类型)
运行结果:
自定义委托
以上的Action委托和Function委托,是微软已经为我们准备好的,那我们自己怎么声明呢,这就是接下来的自定义委托
先说明,委托是一种类(class),所以委托声明在名称空间内,和program类是平级的。如何查看委托是不是类呢,很简单的一个小程序:
namespace DelegateExample_IsClass_
{
class Program
{
static void Main(string[] args)
{
Type t = typeof(Action);
Console.WriteLine(t.IsClass);
}
}
}
结果运行后打印出来的是 True ,这说明委托确实是个类
然后我们就自己声明一个委托,委托的声明格式是这样的:
可访问性 delegate关键字 目标方法返回值类型 委托名字(目标方法的参数列表);
下面看一个小程序:
namespace DelegateExample_custom_delegate_
{
public delegate double Calc(double x,double y); class Program
{
static void Main(string[] args)
{
Calculator calculator = new Calculator();
Calc calc = new Calc(calculator.Add);
Calc calc2 = new Calc(calculator.Sub);
Calc calc3 = new Calc(calculator.Mul);
Calc calc4 = new Calc(calculator.Div); double a = ;
double b = ;
double c = ; c = calc.Invoke(a, b);
Console.WriteLine(c);
c = calc2.Invoke(a, b);
Console.WriteLine(c);
c = calc3.Invoke(a, b);
Console.WriteLine(c);
c = calc4.Invoke(a, b);
Console.WriteLine(c); }
}
class Calculator
{
public double Add(double x, double y)
{
return x + y;
}
public double Sub(double x, double y)
{
return x - y;
}
public double Mul(double x, double y)
{
return x * y;
}
public double Div(double x, double y)
{
return x / y;
}
}
}
这个程序中,我们自己声明了一个叫Calc的委托,因为我们的方法都是double的参数,double的返回值,所以是 "double Calc" 。剩下的就没什么大问题了。
自定义委托时有几点需要注意:
委托与所封装的方法必须“类型兼容”,也就是说
返回值的数据类型要一致
参数列表在个数和数据类型上一致(参数名不需要一样)
再就是声明的时候要声明在正确的位置处,要声明在名称空间中(与program平级),但是C#又允许嵌套类型存在,声明在Program类里又编译的过去,但不要这么干,该放哪就放哪(要放在名称空间里与其他类平级)
----------------------------------------------------------------------------------------------
迫于时间缘故,这篇博客就先写这么多,放假后会写完后面的
希望博友们指出我的问题所在,指出我哪里理解错了,共同交流,共同进步!
To be continued!
C#——委托(1)的更多相关文章
- HTML 事件(三) 事件流与事件委托
本篇主要介绍HTML DOM中的事件流和事件委托. 其他事件文章 1. HTML 事件(一) 事件的介绍 2. HTML 事件(二) 事件的注册与注销 3. HTML 事件(三) 事件流与事件委托 4 ...
- C#基础篇 - 理解委托和事件
1.委托 委托类似于C++中的函数指针(一个指向内存位置的指针).委托是C#中类型安全的,可以订阅一个或多个具有相同签名方法的函数指针.简单理解,委托是一种可以把函数当做参数传递的类型.很多情况下,某 ...
- [.NET] C# 知识回顾 - 委托 delegate (续)
C# 知识回顾 - 委托 delegate (续) [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6046171.html 序 上篇<C# 知识回 ...
- [C#] C# 知识回顾 - 委托 delegate
C# 知识回顾 - 委托 delegate [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6031892.html 目录 What's 委托 委托的属性 ...
- 9、委托、事件、Lambda
开始 关于委托,肯定是要有问题的. 第一个问题,委托用来干什么? 看.net中的表述:在.net平台下,委托类型用来定义和相应应用程序中的回调.(回调?处理内存中两个实体双向通信的一种技术.) 第 ...
- iOS 委托与文本输入(内容根据iOS编程编写)
文本框(UITextField) 本章节继续编辑 JXHypnoNerd .文件地址 . 首先我们继续编辑 JXHypnosisViewController.m 修改 loadView 方法,向 ...
- C#委托异步调用
参考页面: http://www.yuanjiaocheng.net/webapi/mvc-consume-webapi-get.html http://www.yuanjiaocheng.net/w ...
- JavaScript事件代理和委托(Delegation)
JavaScript事件代理 首先介绍一下JavaScript的事件代理.事件代理在JS世界中一个非常有用也很有趣的功能.当我们需要对很多元素添加事件的时候,可以通过将事件添加到它们的父节点而将事件委 ...
- .NET面试题系列[7] - 委托与事件
委托和事件 委托在C#中具有无比重要的地位. C#中的委托可以说俯拾即是,从LINQ中的lambda表达式到(包括但不限于)winform,wpf中的各种事件都有着委托的身影.C#中如果没有了事件,那 ...
- .NET基础拾遗(4)委托、事件、反射与特性
Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理基础 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开 ...
随机推荐
- adaptive heuristic critic 自适应启发评价 强化学习
https://www.cs.cmu.edu/afs/cs/project/jair/pub/volume4/kaelbling96a-html/node24.html [旧知-新知 强化学习:对 ...
- YTST_CX_0001(ALV栏位汇总)
*********************************************************************** * Title : X ...
- selenium超时设置
设置超时时间 from selenium import webdriverdriver=webdriver.Chrome()driver.set_page_load_timeout(5)driver. ...
- CodeForces - 799B T-shirt buying 【贪心】
题目链接 http://codeforces.com/problemset/problem/799/B 题意 给出N件衣服 pi 表示 第i件衣服的价格 ai 表示 第i件衣服的前面的颜色 bi 表示 ...
- Linux常用命令全集
一,安装和登陆命令1,进入图形界面 startx 2,进入图形界面 init 5 3,进入字符界面 init 34,登陆 login 5,关机 poweroff -p 关闭机器的时候关闭电源-n 在关 ...
- Spring Boot2.0之 原理—创建内置Tomcat容器
前面所述的https://www.cnblogs.com/toov5/p/9823728.html 中的第一条先不赘述了,就是玩了maven 重点介绍后两条 首先内置Tomcat: SpringBoo ...
- 1 准备学习redis
首先,当然是搜索相关资料了 1 Redis 设计与实现 http://redisbook.com/ 2 Redis快速入门 http://www.yiibai.com/redis/redis_quic ...
- matlab的代码注释
1.注释一块代码: %{ 此处代码块 %} 2.注释数行代码: 先选中,然后用组合键Ctrl+R 取消注释,用组合键Ctrl+T 3.双%%的作用:代码分块运行,点击双%%之间的代码,再点Run Se ...
- python-多线程1
程序\进程\线程的关系: 程序(program) 一组功能集合的静态描述,程序至少有一个进程 进程(process) 进程是系统进行资源分配和调度的,他们拥有自己独立的空间,进程至少有一个线程 线程( ...
- L98
If there's one thing to be taught, it's dreams are made to be caught.唯有一事值得谨记,有梦想就要奋力追逐Capital punis ...