• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C#教程 > c# 委托详解

c# 委托详解

作者:liyongke 字体:[增加 减小] 来源:互联网 时间:2017-05-28

liyongke 通过本文主要向大家介绍了马桶c的个人空间,c语言,欲情 c max,维生素c,crh2c等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

委托是一个类型。C#中的委托是面向对象的,并且它是类型安全的 当创建委托实例的时候,创建的实例会包含一个调用列表,在调用列表中可以包含多个方法。每个方法称作一个调用实体。调用实体可以是静态方法,也可以是实例方法。如果是实例方法,则该调用实体包含调用该实例方法的实例。委托并不关心它所调用方法所属的类,它只关心被调用方法与委托的类型是否兼容。 下面是代码实例:

using System;
namespace LycheeTest{
 public delegate void D(int a, int b);
 public class Test {
 public D myDelegate;
 public Test() {
  myDelegate = new D(Show1);
 }
 private static void Show1(int a, int b) {
  Console.WriteLine("方法 Show1 被调用,两个实参相加的值是:{0}", a + b);
 }
 private void Show2(int a, int b) {
  Console.WriteLine("方法 Show2 被调用,两个实参相加的值是:{0}", a + b);
 }
 private void Show3(int a, int b) {
  Console.WriteLine("方法 Show3 被调用,两个实参相加的值是:{0}", a + b);
 }
 }
 public class Program {
 static void Main(string[] args) {
  Test myT = new Test();
  myT.myDelegate(33, 22);
  Console.ReadKey();
 }
 }
}
</div>

这段代码演示的是最简单的一种委托形式。委托类型可以定义在类的外部,也可以定义在类的内部。 本段代码是定义在类的外部。第 3 行代码定义的就是一个委托类型,委托类型的关键字是 delegate,关键字前是委托类型的访问权限修饰符。关键字后是委托类型的返回类型,这个返回类型规定与委托类型兼容 的方法的返回类型必须与之相同。返回类型之后是委托类型的名称。接下来是形参列表,它指定与委托类 型兼容的方法的参数类型和个数必须与之相同。第 5 行代码定义了一个委托类型的变量,它是一个实例字段,访问权限是 public 的。注意委托类型字段的访问权限一定要比委托类型的访问权限低或与委托类型的访问权限相同才可以。第 9 行、第 12 行和第 15 行代码定义了三个方法。其中第 9 行代码是一个静态方法。因为这段代码演示的是最简单的委托使用方法,所以只使用了其中的静态方法。在第 6 行的构造方法中,实例化了委托类型的变量,注意为委托变量的调用列表添加方法,只需要向其构造方法中传递方法名称即可。这是为委托添加调用方法的最基本的一种方法。第 21 行定义了 Test 类的一个实例,然后第 22 行调用了类的委托成员。在调用委托成员的时候,需要向其形参列表传递实参。这就是最基本的委托的使用方法。这段代码的执行结果如下:

方法 Show1 被调用,两个实参相加的值是:55

下面再介绍一种委托类型的使用方法,实例代码如下:

using System;
namespace LycheeTest {
 public delegate void D(int a, int b);
 public class Test {
 public static void Show1(int a, int b) {
  Console.WriteLine("方法 Show1 被调用,两个实参相加的值是:{0}", a + b);
 }
 public void Show2(int a, int b) {
  Console.WriteLine("方法 Show2 被调用,两个实参相加的值是:{0}", a + b);
 }
 public void Show3(int a, int b) {
  Console.WriteLine("方法 Show3 被调用,两个实参相加的值是:{0}", a + b);
 }
 }
 public class Program {
 static void Main(string[] args) {
  Test myT = new Test();
  D myDelegate = new D(Test.Show1);
  D myDelegate1 = new D(myT.Show2);
  D myDelegate2 = new D(myT.Show3);
  myDelegate(22, 33);
  myDelegate1(33, 44);
  myDelegate2(55, 66);
  Console.ReadKey();
 }
 }
}
</div>

这段代码取消了类中的委托类型字段,而是将委托类型作为一个类来看待。在包含入口点方法的类中,首先第 17 行定义了 Test 类的一个变量并做了实例化。因为要向委托传递类的实例方法,所以必须有类的实 例存在,才能引用类的实例方法。第 18 行定义了一个委托类型的变量,并实例化,这里需要注意,因为委托并不是类中的一个成员了, 所以向其构造方法传递静态方法的时候,需要以类名引用。第 19 行也定义了一个委托类型的变量,在向其传递实例方法的时候,需要以类的实例来引用。第 20 行代码的情况同第 19 行代码一样。在向委托传递方法的时候,需要传递方法名,而不需要方法的形参列表。第 21 行到第 23 行是对委托的调用,这时要为其传递方法的实参。这段代码的执行结果如下:

方法 Show1 被调用,两个实参相加的值是:55 
方法 Show2 被调用,两个实参相加的值是:77 
方法 Show3 被调用,两个实参相加的值是:121
</div>

委托的访问修饰符

当委托位于类的外部时,可以使用的访问修饰符包括 public 和 internal。如果什么也不写,默认是internal 的。当委托位于类的内部时,可以使用的访问修饰符包括 public、protected、internal、protected

using System;
namespace LycheeTest{
 public class Test {
 protected delegate void D(int a, int b);
 private delegate void D1(int a, int b);
 protected internal delegate void D2(int a, int b);
 internal delegate void D3(int a, int b);
 private D myD;
 private D1 myD1;
 private D2 myD2;
 private D3 myD3;
 public Test() {
  myD = new D(Show1);
  myD1 = new D1(Show1);
  myD2 = new D2(Show1);
  myD3 = new D3(Show1);
 }
 public static void Show1(int a, int b) {
  Console.WriteLine("方法 Show1 被调用,两个实参相加的值是:{0}", a + b);
 }
 public void Show2(int a, int b) {
  Console.WriteLine("方法 Show2 被调用,两个实参相加的值是:{0}", a + b);
 }
 public void Show3(int a, int b) {
  Console.WriteLine("方法 Show3 被调用,两个实参相加的值是:{0}", a + b);
 }
 public void Use() {
  myD(11, 12);
  myD1(22, 45);
  myD2(55, 78);
  myD3(345, 100);
 }
 }
 class Test1: Test {
 private D Test1D;
 private D2 Test1D2;
 private D3 Test1D3;
 public Test1() {
  Test1D = new D(Test.Show1);
  Test1D2 = new D2(Test.Show1);
  Test1D3 = new D3(Test.Show1);
 }
 public void Use1() {
  Test1D(22, 45);
  Test1D2(44, 45);
  Test1D3(77, 78);
 }
 }
 public class Program {
 static void Main(string[] args) {
  Test1 myT1 = new Test1();
  myT1.Use();
  myT1.Use1();
  Console.ReadKey();
 }
 }
}
</div>

代码的第 4 行在类的内部定义了委托类型,它作为类的成员定义,访问权限是 protected,它可以被本类内部访问,也可以被派生类访问。代码的第 5 行定义的委托类型,访问权限是 private 的,它只可以被本类内部访问。代码的第 6 行定义的 protected internal 访问权限的委托类型,可以被本程序集访问, 还可以被派生类访问,而不管派生类位于哪个程序集。第 7 行定义的委托类型是 internal 的,它只可以被本程序集访问。因为所有这几种委托类型都可以被本类内部访问,所以第 10 行到第 13 行定义了它们的变量。第 12 行的实例构造方法中,对这四个委托类型的变量进行了实例化,并为它们的调用列表加入了方法 Show1。Show1 是一个静态方法,但是在类内部传入委托类型的构造方法时,不需要使用类名引用。第 27 行定义了实例方法,在方法内部调用了这四个委托,并为其传入实参。第 34 行代码又定义了一个类,它继承自基类 Test。因为基类中的委托类型只有 D、D2 和 D3 可以被派生类访问,所以第 35 行到第 37 行定义了它们的变量。注意,虽然它们和基类中的委托变量是同一种类型, 但是它们是不同的委托。在第 38 行的实例构造方法中,为这三个委托类型的变量创建实例,并为其调用列表加入方法,因为静态方法 Show1 也被派生类所继承,所以这里传入的方法名,可以使用类名引用,也可以不使用类名引用。 第 43 行定义了一个实例方法,方法内部调用了这三个委托,并为其传入实参。第 51 行定义了派生类的实例,然后调用实例方法Use和Use1。这段代码的执行结果如下:

方法 Show1 被调用,两个实参相加的值是:23 
方法 Show1 被调用,两个实参相加的值是:67 
方法 Show1 被调用,两个实参相加的值是:133
方法 Show1 被调用,两个实参相加的值是:445 
方法 Show1 被调用,两个实参相加的值是:67 
方法 Show1 被调用,两个实参相加的值是:89 
方法 Show1 被调用,两个实参相加的值是:155
</div>

因为 D 和 D2 的访问权限被定义成了 protected 和 protected internal。所以下面来验证在其它程序集中是否可以访问它们。首先要将本段代码中的包含 Main 方法的类去掉,然后在它的项目属性中将它改变为类库。接下来新建一个控制台项目,并物理上引用这个类库。控制台项目的代码如下:

using System;
using LycheeTest;
namespace LycheeTest1{
 class Program: Test {
 private D pD;
 private D2 pD2;
 public Program() {
  pD = new D(Show1);
  pD2 = new D2(Show1);
 }
 public void Use3() {
  pD(34, 33);
  pD2(12, 11);
 }
 static void Main(string[] args



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • C#利用ReportViewer生成报表
  • C#基于正则去掉注释的方法示例
  • C#中new的用法及与override的区别分析
  • C#实现两个richtextbox控件滚动条同步滚动的简单方法
  • C# for循环的经典案例集锦
  • C#操作word的方法示例
  • C#使用WebClient登录网站并抓取登录后的网页信息实现方法
  • C# WinForm制作异形窗体与控件的方法
  • C#实现Excel表数据导入Sql Server数据库中的方法
  • C#使用NPOI上传excel

相关文章

  • 2017-05-28C#获取指定PDF文件页数的方法
  • 2017-05-28WinForm项目开发中NPOI用法实例解析
  • 2017-05-28c#使用多线程的几种方式示例详解
  • 2017-05-28深入理解C#索引器(一种支持参数的属性)与属性的对比
  • 2017-05-28C#实现DataList里面嵌套DataList的折叠菜单
  • 2017-05-28C#中把英文字母转换为大写或小写的方法
  • 2017-05-28C#使用 Salt + Hash 来为密码加密
  • 2017-05-28C#调用系统API指定快捷键的方法
  • 2017-05-28C#实现清空回收站的方法
  • 2017-05-28Windows下C#的GUI窗口程序中实现调用Google Map的实例

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • C#画笔Pen画虚线的方法
    • C#中Socket通信用法实例详解
    • 读取图片像素的具体实例
    • C#提示:“在证书存储区中找不到清单签名证书”的解决方法
    • C# 6.0 新特性汇总
    • C#基础:基于const与readonly的深入研究
    • C#动态生成按钮及定义按钮事件的方法
    • C#如何遍历Dictionary
    • C# Socket网络编程实例
    • c# 可疑文件扫描代码(找到木马)(简)

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有