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与数据库开 ...
随机推荐
- 镜像回源主要用于无缝迁移数据到OSS,即服务已经在自己建立的源站或者在其他云产品上运行,需要迁移到OSS上,但是又不能停止服务,此时可利用镜像回写功能实现。
管理回源设置_管理文件_开发指南_对象存储 OSS-阿里云 https://help.aliyun.com/document_detail/31865.html 通过回源设置,对于获取数据的请求以多种 ...
- 使用服务端的临时密钥,不依赖阿里js的putFIle--》阿里oss
<!DOCTYPE html> <html lang='en'> <head> <meta charset='UTF-8'> <title> ...
- 一个小公司的前端笔试HTML CSS JS
网上有这套题的答案,版本也很多,我做了很多参考.本文就当个小笔记,可能有错误,还望指正~ 第1章 Html篇 1. 你做的网页在哪些浏览器测试过?这些浏览器的内核分别是什么? 浏览器类型 内核 Fi ...
- 我的Android进阶之旅------>Android如何通过自定义SeekBar来实现视频播放进度条
首先来看一下效果图,如下所示: 其中进度条如下: 接下来说一说我的思路,上面的进度拖动条有自定义的Thumb,在Thumb正上方有一个PopupWindow窗口,窗口里面显示当前的播放时间.在Seek ...
- redux和mobx比较(一)
Redux vs Mobx 那么具体到这两种模型,又有一些特定的优缺点呈现出来,先谈谈 Redux 的优势: 数据流流动很自然,因为任何 dispatch 都会导致广播,需要依据对象引用是否变化来控制 ...
- <J2EE学习笔记>关于Servlet的讲义
题外话:接触java又是半年之前的事情了,当初好好学了java却把cpp给忘了,到现在又把手里发热的cpp给放下重新捡起来java,究竟这两种OOP语言我能不能清晰分开记住呢 以下全部课件来自于同济大 ...
- 9.1 NOIP普及组试题精解(1)
9-1 series1.c #include <stdio.h> int main() { float s=0.0,k; int n; printf("输入数字k(1~15):& ...
- python清空tree.insert()
import tkinter from tkinter import ttk # 导入内部包 li = [', '男'] root = tkinter.Tk() root.title('测试') tr ...
- css3-rotate实现超炫环形旋转特效
css3-rotate实现超炫环形旋转特效,css3特效,环形旋转,圆形旋转,css3-rotate实现超炫环形旋转特效是一款采用css3 rotate实现的蓝色环形旋转特效代码. http://ww ...
- 动态创建TeeChart的简便方法
最近在项目中使用Teechart ocx版本替换了labview的老版本控件,显示效果和效率均有提高,但是却遇到多线程下报access violation的问题. 翻遍大小论坛,最后在官网论坛找到相同 ...