C#委托详解(1):什么是委托
本系列文章将详细探讨C#中的委托,列举其主要的实现方式,并分析其在设计层面和编码层面带来的好处,最后会讨论其安全性和执行效率等。
什么是委托?
委托是寻址方法的.NET版本,使用委托可以将方法作为参数进行传递。委托是一种特殊类型的对象,其特殊之处在于委托中包含的只是一个活多个方法的地址,而不是数据。
委托虽然看起来像是一种类型,但其实定义一个委托,是定义了一个新的类。下面这行代码,定义了一个委托,使用ILDasm.exe查看其生成的IL代码如图所示:
//定义委托,它定义了可以代表的方法的类型,但其本身却是一个类
public delegate int methodDelegate(string str);
由图中红色框线中可以看出,.NET将委托定义为一个密封类,派生自基类System.MulticastDelegate,并继承了基类的三个方法(稍后讨论这三个)。
委托与函数指针的区别
1、安全性:C/C++的函数指针只是提取了函数的地址,并作为一个参数传递它,没有类型安全性,可以把任何函数传递给需要函数指针的地方;而.NET中的委托是类型安全的。
2、与实例的关联性:在面向对象编程中,几乎没有方法是孤立存在的,而是在调用方法前通常需要与类实例相关联。委托可以获取到类实例中的信息,从而实现与实例的关联。
3、本质上函数指针是一个指针变量,分配在栈中;委托类型声明的是一个类,实例化为一个对象,分配在堆中。
4、委托可以指向不同类中具有相同类型返回参数和签名的函数,函数指针则不可以。
namespace ConsoleApplication1
{
//定义委托,它定义了可以代表的方法的类型,但其本身却是一个类
public delegate void methodDelegate(string str);
class Program
{
static void Main(string[] args)
{
Student student = new Student();
Teacher teacher = new Teacher("王老师");
methodDelegate methodDelegate1 = new methodDelegate(student.getStudentName);
methodDelegate1 += teacher.getTeacherName; //可以指向不同类中的方法!
//methodDelegate1 += teacher.getClassName; 指向签名不符的方法时提示错误!
methodDelegate1.Invoke("张三");
Console.ReadLine();
}
} class Student
{
private String name = "";
public Student (String _name)
{
this.name = _name ;
}
public Student() {}
public void getStudentName(String _name)
{
if (this.name != "" )
Console.WriteLine("Student's name is {0}", this.name);
else
Console.WriteLine("Student's name is {0}", _name);
}
} class Teacher
{
private String name;
public Teacher(String _name)
{
this.name = _name;
}
public void getTeacherName(String _name)
{
if (this.name != "")
Console.WriteLine("Teacher's name is {0}", this.name);
else
Console.WriteLine("Teacher's name is {0}", _name);
}
public string getClassName()
{
return "Eanlish";
}
}
}
上述测试代码运行结果如下:

当指向签名不符的方法时会提示如下错误,证实了委托的安全性。

本篇结束,下一篇介绍委托的主要实现方式。
C#委托详解(1):什么是委托的更多相关文章
- C#委托详解(3):委托的实现方式大全(续)
接上篇(C#委托详解(2):实现方式大全),本篇继续介绍委托的实现方式. 4.Action<T>和Func<T>委托 使用委托时,除了为每个参数和返回类型定义一个新委托类型之外 ...
- C#委托详解(2):实现方式大全
本系列文章将详细探讨C#中的委托,列举其主要的实现方式,并分析其在设计层面和编码层面带来的好处,最后会讨论其安全性和执行效率等. 接上篇(C#委托详解(1):什么是委托)介绍完什么是委托之后,来看看C ...
- C#事件与委托详解
from https://www.cnblogs.com/sjqq/p/6917497.html C#事件与委托详解[精华 多看看] Delegatedelegate是C#中的一种类型,它实际上是一个 ...
- C# 委托详解(一)
1.委托简单例子 class eeProgram { // 声明delegate对象 public delegate string CompareDelegate(int a, int b); // ...
- C#事件与委托详解【精华 多看看】
Delegate delegate是C#中的一种类型,它实际上是一个能够持有对某个方法的引用的类.与其它的类不同,delegate类能够拥有一个签名(signature),并且它"只能持有与 ...
- c#之委托详解(Delegate)
一.委托的概念 在我们学习委托之前,我们来了解下,什么是委托呢? 官方概念:委托是一种安全地封装方法的类型,它与 C 和 C++ 中的函数指针类似.与 C 中的函数指针不同,委托是面向对象的.类型安全 ...
- Kotlin属性委托系统总结与提供委托详解
属性委托总结回顾: 在前三次已经将Kotlin委托相关的知识点进行了完整的学习了,具体博文如下: https://www.cnblogs.com/webor2006/p/11369019.html h ...
- C#多播委托详解
包含多个方法的委托成为多播委托,调用多播委托,可以按照顺序连续调用多个方法,因此,委托的签名就必须返回void;否则,就只能得到委托调用的最好一个方法的结果 1.多播委托可以用运算符"+&q ...
- JavaScript 事件委托详解
基本概念 事件委托,通俗地来讲,就是把一个元素响应事件(click.keydown......)的函数委托到另一个元素: 一般来讲,会把一个或者一组元素的事件委托到它的父层或者更外层元素上,真正绑定事 ...
随机推荐
- HTML 5缓存机制:Cache Manifest配置实例
Cache Manifest是HTML 5的一种缓存机制,文章作者直接用博客当测试环境,虽然[color=#444444 !important]应用起来非常简单,但效果却出奇的好.缓存后的速度,简直是 ...
- iOS中僵尸对象的实现方法
什么是僵尸对象?所谓僵尸,就是过度释放的对象.在ios开发中,僵尸对象对于开发人员调试程序来说很有用.我们通常将NSZombieEnabled环境变量设置为YES来打开僵尸对象,但这会导致所有的对象都 ...
- ios网络:应用一个请求的7个步骤
Splitting big tasks into small tasks is often one of the best ways to solve a problem. Thus, in the ...
- EXT格式误删除恢复
http://hatemysql.com/ 1.从/proc文件系统恢复数据#lsof |grep -i deletecat 11791 root 1w REG 253,0 94 1048589 /h ...
- css3动画响应式404页面
PC端效果: 模拟触屏端效果: 兼容性:触屏端及桌面端(优雅降级至IE6) 模板下载: http://pan.baidu.com/s/1o67ftc2
- delphi 更改不了窗体的标题
delphi定义变量名千万要注意,不能和关键字同名,今天我无意间定义了一个caption的变量 导致我怎么都不能修改窗的标题.
- MongoDB探索之路(一)——入门
1.MongoDB和传统关系型数据库的比较 2.面向文档的 NoSQL 数据库主要解决的问题不是高性能的并发读写,而是保证海量数据存储的同时,具有良好的查询性能. 3.MongoDB可以作为日志分 ...
- Python核心编程--学习笔记--4--Python对象
现在开始学习Python语言的核心部分.首先了解什么是Python对象,然后讨论最常用的内建类型,接下来讨论标准类型运算符和内建函数,之后给出对标准类型的不同分类方式,最后提一提Python目前还不支 ...
- Microsoft SqlServer2008技术内幕:T-Sql语言基础-读书笔记-单表查询SELECT语句元素
1.select语句逻辑处理顺序: FORM WHERE GROUP BY HAVING SELECT OVER DISTINCT TOP ORDER BY 总结: 2.FORM子句的表名称应该带上数 ...
- 【转】C# 子窗体如何调用父窗体的方法
网络上有几种方法,先总结如下: 调用窗体(父):FormFather,被调用窗体(子):FormSub. 方法1: 所有权法 //FormFather: //需要有一个公共的 ...
