委托的使用 - 浅谈

一,声明委托

  对于委托,定义它就是要告诉编译器,这种类型的委托表示哪种类型的方法.然后,必须创建该委托的一个或多个委托实例,编译器将在后台创建表示该委托的一个类.

  因为定义委托基本上是定义一个新类,所以可以在定义类的任何相同地方定义委托.

  在术语方面,和"类,对象"不同."类"表示的是较为广义的定义,"对象"表示类的实例.但是委托只有一个术语,在创建委托实例时,所创建的委托的实例仍然称为委托.

  如下显示委托的声明方式:

//声明委托.
private delegate string GetAString();

二,使用委托

  如下例子:

1 int x = 5;
2 //通过委托的方式.
3 GetAString stringMethod = new GetAString(x.ToString);
4 Console.WriteLine(stringMethod());  

  也可以使用委托推断,只需将地址传递给委托类型的变量(在后台,C#编译器会做同样的处理,即会在后台创建一个委托实例 "new GetAString(x.ToString)"):  

1 //使用委托推断,只需将地址传递给委托实例.
2 GetAString secondMethod = x.ToString;

  实际上,调用委托时,给委托实例提供圆括号与调用委托的Invoke()方法,是完全相同的:

1 Console.WriteLine(stringMethod());  //委托方式1(使用圆括号的方式).
2 Console.WriteLine(stringMethod.Invoke());   //委托方式2(使用调用Invoke()方法的方式).

  原因是对于委托变量stringMethod,C#编译器会调用stringMethod.Invoke()代替stringMethod().

  值得注意的是,在给一个委托类型的变量赋值的时候,方法的名称不能带有"()"括号,上述例子,调用 x.ToString()方法,会返回一个不能赋予委托变量的字符串对象(而不是方法的地址).

  委托的一个特征是,它们是类型安全的,可以确定被调用的方法的签名是正确的.但是委托不关心在什么类型上调用改方法,甚至不考虑方法是静态的,还是实例方法.

  如下例子演示了委托可以使用实例方法,也可以使用静态方法:

  Currency结构的声明:

 1 namespace Wrox.ProCSharp.Delegates {
 2     struct Currency {
 3         public uint Dollars;
 4         public ushort Cents;
 5
 6         public Currency(uint dollars, ushort cents) {
 7             this.Dollars = dollars;
 8             this.Cents = cents;
 9         }
10
11         public override string ToString() {
12             return string.Format("${0}.{1,-2:00}", Dollars, Cents);
13         }
14
15         public static string GetCurrencyUnit() {
16             return "Dollar";
17         }
18
19         public static explicit operator Currency(float value) {
20             checked {
21                 uint dollars = (uint)value;
22                 ushort cents = (ushort)((value - dollars) * 100);
23                 return new Currency(dollars, cents);
24             }
25         }
26
27         public static implicit operator float(Currency value) {
28             return value.Dollars + (value.Cents / 100.0f);
29         }
30
31         public static implicit operator Currency(uint value) {
32             return new Currency(value, 0);
33         }
34
35         public static implicit operator uint(Currency value) {
36             return value.Dollars;
37         }
38     }
39
40 }

在住函数中调用:

 1 using System;
 2
 3 namespace Wrox.ProCSharp.Delegates
 4 {
 5     class Program
 6     {
 7         private delegate string GetAString();
 8
 9         static void Main()
10         {
11             int x = 40;
12             GetAString firstStringMethod = x.ToString;
13             Console.WriteLine("String is {0}", firstStringMethod());
14
15             Currency balance = new Currency(34, 50);
16
17             // firstStringMethod references an instance method
18             firstStringMethod = balance.ToString;
19             Console.WriteLine("String is {0}", firstStringMethod());
20
21             // firstStringMethod references a static method
22             firstStringMethod = new GetAString(Currency.GetCurrencyUnit);
23             Console.WriteLine("String is {0}", firstStringMethod());
24
25         }
26     }
27 }

  输出:

String is 40
String is $34.50
String is Dollar

      

时间: 2025-01-02 16:26:29

委托的使用 - 浅谈的相关文章

浅谈委托和事件(一)

浅谈委托和事件(一) 关于委托和事件,可能是.NET或者说是面向对象编程语言中的一个比较重要又比较难以理解的概念.关于这一话题,园子里的人也写了很多文章,最经典的可能就是张子阳的C#中的委托和事件这两篇文章了,之前也看过MSDN 上的WebCast深入 "委托和事件".可能和很多人一样,刚开始读的时候,觉得很清楚,但是过了一段时间好像又忘记了委托和事件的区别,知道很久以前,在一次面试中我被问到委托和事件有什么区别,一下子就说不清了. 所以这里稍微理一下,也算是自己的一个总结.当然,还是

浅谈ThreadPool 线程池(引用)

出自:http://www.cnblogs.com/xugang/archive/2010/04/20/1716042.html 浅谈ThreadPool 线程池 相关概念: 线程池可以看做容纳线程的容器: 一个应用程序最多只能有一个线程池: ThreadPool静态类通过QueueUserWorkItem()方法将工作函数排入线程池: 每排入一个工作函数,就相当于请求创建一个线程: 线程池的作用: 线程池是为突然大量爆发的线程设计的,通过有限的几个固定线程为大量的操作服务,减少了创建和销毁线程

浅谈Kotlin(三):类

浅谈Kotlin(一):简介及Android Studio中配置 浅谈Kotlin(二):基本类型.基本语法.代码风格 前言: 已经学习了前两篇文章,对Kotlin有了一个基本的认识,往后的文章开始深入介绍Kotlin的实战使用. 本篇介绍Kotlin中类的使用. 一.表现形式 首先看一段Java中定义类的形式,定义三个属性,每一个属性对应一个get.set方法,有一个toString()方法 /* * @author xqx * @emil [email protected] * create

浅谈产业界与学术界的合作研究(转)

[编者注:原文可参阅: http://blog.sciencenet.cn/blog-414166-795432.html ] 最近网络上有一个流传甚广的微故事:"某企业引进了一条香皂包装线,结果发现经常会有空盒流过.厂长聘请一个博士后花了200 万设计出一个全自动分检系统.一个乡镇企业遇到了同样的问题,民工花90 元买了一台大电扇放在生产线旁,一有空盒经过便会吹走."这个微故事不断出现在笔者的视线中,想必在网络上得到了公众的认可.引起了共鸣,所以大家争相转发.平心而论,大多数人的内心

浅谈 GetHashCode

我们知道,System.Object 类是 .NET Framework 中所有类的最终基类,它是类型层次结构的根,并为派生类提供低级别服务.通常不要求类声明从 Object 的继承,因为继承是隐式的.因为 .NET Framework 中的所有类均从 Object 派生,所以 Object 类中定义的每个方法可用于系统中的所有对象.派生类可以而且确实重写这些方法中的某些,其中包括: Equals - 支持对象间的比较. Finalize - 在自动回收对象之前执行清理操作. GetHashCo

浅谈 jQuery 事件源码定位问题

原文:浅谈 jQuery 事件源码定位问题 昨天群里有人问了个事件源码定位的问题,简单描述下是这样的. 在一个不是自己写的页面上,如何快速定位到他绑定的事件代码在哪?(页面用的是jQuery)这个问题,说难不难,说简单也没那么简单,万一用的是委托之类也会麻烦点. 在 chrome 的控制台里有个 Event Listeners,这里会显示你所选择元素的事件,如果是原生事件,他会直接显示,你点击一下事件就会跳到对应代码里了,可是 jQuery 绑定的事件却不是这样的,你点击后只会跳到 jQuery

转:浅谈程序员的英语学习

转自:http://www.cnblogs.com/haoyifei/p/5687235.html 浅谈程序员的英语学习 作为在中国工作的程序员,不懂得英语似乎也不妨碍找到好工作,升职加薪.但程序员这个工种则稍有不同,因为程序,尤其是高级语言,基本上都是由英语和数字表达式构成的.英语对于程序员十分重要.我的大学本科全部采用英文教学,工作时也经常会遇到外国人,和他们谈笑风生,自认为自己的英语水平比园子的平均水平高一点.下面我就根据自己的经验来说说英语的学习方法. 为什么要学习英语 学好英语你可以直

浅谈C#中堆和栈的区别(附上图解)

线程堆栈:简称栈 Stack 托管堆: 简称堆 Heap 使用.Net框架开发程序的时候,我们无需关心内存分配问题,因为有GC这个大管家给我们料理一切.如果我们写出如下两段代码: 代码段1: public int AddFive(int pValue) { int result; result = pValue + 5; return result; } 代码段2: public class MyInt { public int MyValue; } public MyInt AddFive(i

浅谈线程池(下):相关试验及注意事项

三个月,整整三个月了,我忽然发现我还有三个月前的一个小系列的文章没有结束,我还欠一个试验!线程池是.NET中的重要组件,几乎所有的异步功能依赖于线程池.之前我们讨论了线程池的作用.独立线程池的存在意义,以及对CLR线程池和IO线程池进行了一定说明.不过这些说明可能有些"抽象",于是我们还是要通过试验来"验证"这些说明.此外,我认为针对某个"猜想"来设计一些试验进行验证是非常重要的能力,如果您这方面的能力略有不足的话,还是尽量加以锻炼并提高吧. C