第十七章 委托
一、 委托的使用
静态委托和实例委托,使用方法类似,这里给出一个使用可变参数委托的例子:
using System;
public class DelCls
{
public delegate void DelDef(params string[] strParams);
public static void CallDel(DelDef dd)
{
if(dd != null) //请务必在此处进行判断,这是个好习惯
{
dd("Hello", "world");
}
}
}
public class DelIns
{
//声明为private(私有)成员并不影响在类型内部使用委托
private static void ClsCallStr(params string[] strParams) //类型方法
{
//将字符串数组并顺序输出
foreach(string str in strParams)
{
Console.Write("{0} ", str);
}
Console.WriteLine();
}
public void InsCallStr(params string[] strParams) //实例方法
{
//将字符串数组并反序输出
for(int i = strParams.Length - 1; i >= 0; i --)
{
Console.Write("{0} ", strParams[i]);
}
Console.WriteLine();
}
public static void Main()
{
DelIns di = new DelIns();
DelCls.DelDef dd = null;
Console.WriteLine("combine two delegate:");
dd += new DelCls.DelDef(DelIns.ClsCallStr);
dd += new DelCls.DelDef(di.InsCallStr);
DelCls.CallDel(dd);
Console.WriteLine("remove the first delegate:");
dd -= new DelCls.DelDef(DelIns.ClsCallStr);
DelCls.CallDel(dd);
}
}
/*运行结果
combine two delegate:
Hello world
world Hello
remove the first delegate:
world Hello
*/
在C#中使用委托方法:
l 创建委托所使用的方法必须和委托声明相一致(参数列表、返回值都一致)
l 利用 +=、-=来进行委托的链接或取消链接或直接使用Delegate.Combine和Delegate.Remove方法来实现
l 使用MulticastDelegate的实例方法GetInvocationList()来获取委托链中所有的委托
二、 委托揭秘
所有的委托都继承自MulticastDelegate,编译器在编译时刻为委托的声明生成了一个完整的委托类,重点注意其中的一些成员:
ü 构造函数,传入委托的目标对象(实例)及指向回调方法的整数
ü 继承自MulticastDelegate的_target(System.Object)字段
ü 继承自MulticastDelegate的_methodPtr(System.Int32)字段
ü 继承自MulticastDelegate的_prev(System.MulticastDelegaet)字段
ü 生成的与方法声明相一致Invoke函数用以调用方法
可利用MulticastDelegate中的Method及Target属性来考察_methodPtr及_target字段的性质。
关于编译器生成的委托类及Invoke方法的调用情况,可通过使用ILDAsm.exe查看执行文件的IL代码获得
将上例中类型DelIns中的Main方法作如下修改,以实验GetInvocationList及MulticastDelegate中属性的使用:
public class DelIns
{
…
public static void Main()
{
…
Delegate[] arrDel = dd.GetInvocationList();
foreach(DelCls.DelDef d in arrDel)
{
Console.WriteLine("Object type: {0}, Method name: {1}",
(d.Target != null) ? d.Target.GetType().ToString() : "null",
d.Method.Name);
}
…
}
…
}
/*运行结果
…
Object type: null, Method name: ClsCallStr
Object type: DelIns, Method name: InsCallStr
…
*/
三、 委托判等
首先判断_methodPtr及_target字段是否相等,若不等则返回false;
若相等,继续判断_prev是否为null(指向委托链头部的委托),若为null,则相等返回true;
若不等,继而判断委托链上所有委托对象,重复上述步骤。
可见牵涉到委托链的时候是个递归判断的过程。
四、 委托链
l 首先被加入到委托链中的委托位于委托链的尾部,但首先被调用,这是因为Invoke中利用递归对委托函数进行调用,这样位于头部的委托最后被调用。
l 委托调用后的返回值,只是最后一次被调用方法的返回值,即委托链头部委托的返回值
l 每调用一次Remove方法只删除匹配的第一个委托链
五、 委托与反射
以下是.net framework sdk文档提供的Delegate.CreateDelegate方法列表:
创建指定类型的委托以表示指定的静态方法。
[C#] public static Delegate CreateDelegate(Type, MethodInfo);
创建指定类型的委托,该委托表示要对指定的类实例调用的指定实例方法。
[C#] public static Delegate CreateDelegate(Type, object, string);
创建指定类型的委托,该委托表示指定类的指定静态方法。
[C#] public static Delegate CreateDelegate(Type, Type, string);
创建指定类型的委托,该委托表示要按指定的大小写敏感度对指定类实例调用的指定实例方法。
[C#] public static Delegate CreateDelegate(Type, object, string, bool);
下面的示例演示了创建静态方法委托、实例方法委托以及动态调用委托:
using System;
using System.Reflection;
public class DelReflection
{
public delegate void GoGo(string strPam, Int32 nPam);
public static void ClsGo(string strPam, Int32 nPam)
{
Console.WriteLine("In class, String:{0}, Int32:{1}", strPam, nPam);
}
public void InsGo(string strPam, Int32 nPam)
{
Console.WriteLine("In instance, String:{0}, Int32:{1}", strPam, nPam);
}
public static void Main()
{
Delegate d = null;
d = Delegate.CreateDelegate(typeof(GoGo), typeof(DelReflection), "ClsGo");
if(d != null)
d.DynamicInvoke(new Object[]{"Hello", 45});
DelReflection dr = new DelReflection();
d = Delegate.CreateDelegate(typeof(GoGo), dr, "InsGo");
if(d != null)
d.DynamicInvoke(new Object[]{"Hello", 45});
}
}
/*运行结果
In class, String:Hello, Int32:45
In instance, String:Hello, Int32:45
*/
分享到:
相关推荐
《C#与.NET3.0高级程序设计》是一本深入探讨C#编程语言和.NET Framework 3.0核心特性的专业书籍。这本书旨在帮助开发者掌握更高级的C#编程技巧和.NET 3.0框架的使用,从而提升软件开发的能力和效率。读书笔记主要...
VB.NET是Visual Basic的.NET版本,它继承了VB的易读性和强大的GUI设计能力,并且完全拥抱了.NET框架。在本项目中,VB.NET被用来作为调用DLL的“前端”程序。VB.NET通过.NET Framework的COM互操作性,可以无缝地调用...
这部分笔记可能包含.NET框架的基础知识,如CLR(Common Language Runtime)的工作原理、内存管理(垃圾回收)、线程管理和异步编程模型等。此外,还可能涉及.NET Framework与.NET Core的区别,以及跨平台开发的讨论...
【VS.NET学习笔记】 Visual Studio .NET(简称VS.NET)是微软公司开发的一款强大的集成开发环境,用于构建基于.NET Framework的应用程序。这个平台为开发者提供了丰富的工具和功能,支持多种编程语言,如C#、VB.NET...
通过阅读这些笔记,我们可以深入理解面向对象的核心概念,并掌握在.Net环境下如何运用设计模式来解决实际问题。 首先,面向对象编程(Object-Oriented Programming,简称OOP)是软件开发中的主要编程范式,其核心...
.NET框架是Microsoft开发的一个软件框架,旨在为跨平台应用程序提供统一的编程模型。它包含一个公共语言运行时(CLR),提供了内存管理、安全性和异常处理等服务,以及一个类库,包含了广泛的功能,如数据库访问、...
使用 .NET 框架轻松开发完美的 Web 窗体控件.do 使用 TreeView IE Web 控件.doc 关于ASP.Net中的时间处理.txt 关于上下文.doc 创建可分页、可排序的 DataGrid.doc 创建用于 ASP.NET 的分页程序控件.doc 创建...
1. **.NET Framework概述**:首先,了解.NET框架的起源和发展,它是微软推出的一种应用程序框架,用于构建和运行基于Windows的软件。它提供了许多服务,如类库、运行时环境(CLR)、垃圾回收机制等,使得开发者能够...
ASP.NET 2.0是微软开发的一个用于构建Web应用程序的框架,它极大地简化了Web开发过程,特别是对于数据操作提供了强大的支持。在这个压缩包中,包含的三个文档——"ASP.NET_2.0中的数据操作.chm"、"ASP.NET中文手册....
在.NET框架中,WPF(Windows Presentation Foundation)是用于构建桌面应用程序的强大工具,而dotnet则是这个框架的基础。本文档“dotnet 读 WPF 源代码笔记 AppDomainShutdownMonitor 的设计”深入探讨了WPF源代码...
同时,了解.NET框架的其他服务,如配置管理、异常处理、安全性以及全球化支持,将使开发者能够构建更全面的应用程序。 总的来说,C#和.NET的学习涵盖了广泛的编程概念和技术,从基础的语法结构到复杂的系统设计。...
5. **.NET框架高级特性**:可能包括LINQ(Language Integrated Query)、反射、泛型、委托、匿名方法、异步编程等,这些是提升.NET编程效率的关键。 6. **单元测试与持续集成**:可能包含NUnit、Moq等工具的使用,...
委托是.NET框架中的一种引用类型,它封装了一个或多个具有相同签名的方法。委托可以用来创建回调函数或者事件处理程序,这样就可以在运行时调用不同的方法,而无需硬编码具体实现。 2. 如何创建委托: 在C#中,...
这本书通过丰富的实例,旨在帮助读者快速掌握.NET框架下的C++编程技巧。 在.NET平台上,Visual C++.NET不仅仅是一个传统的编译型语言,它还支持.NET Framework的组件编程,可以创建托管代码,利用.NET的强大功能。...
通过阅读这本书,读者可以掌握C#的语法特性、面向对象编程原则以及.NET框架下的类库和应用程序开发。 在C#方面,本书详细介绍了以下知识点: 1. C#基础:包括变量、数据类型、运算符、控制流语句等基础知识,是初学...
《Visual C#学习笔记》是一本深入探讨C#编程语言及其在ASP.NET框架下应用的专业教程。这本书旨在为想要掌握C#和ASP.NET技术的读者提供详尽的指导,无论你是初学者还是有一定开发经验的程序员,都能从中受益匪浅。 ...
`.NET框架`的丰富功能和灵活性使得开发人员能够构建高效、可扩展的应用程序。 其次,`面向对象编程(OOP)`是C#的核心部分,包括类、继承、封装和多态等概念。掌握OOP思想和设计原则对于创建可维护和可扩展的代码至关...
C#是一种广泛应用于软件开发的面向对象的编程语言,由微软公司为.NET框架设计。它在现代软件工程中扮演着重要角色,尤其在游戏开发、Web应用、移动应用以及企业级解决方案等领域。以下是对C#学习笔记的详细解读: 1...
7. **.NET框架与库**:C#是.NET平台的一部分,笔记会介绍.NET框架的核心组件,如Common Language Runtime(CLR)和Base Class Library(BCL),以及如何使用各种内置库如System.IO和System.Linq。 8. **ASP.NET Web...
C# 是由 Anders Hejlsberg 和他的团队在 .Net 框架开发期间开发的。C# 是专为公共语言基础结构(CLI)设计的。CLI 由可执行代码和运行时环境组成,允许在不同的计算机平台和体系结构上使用各种高级语言。 C# 程序在 ...