1.委托

C#的委托相当于C/C++中的函数指针。函数指针用指针获取一个函数的入口地址,实现对函数的操作。

委托与C/C++中的函数指针不同在于,委托是面向对象的,是引用类型,对委托的使用要先定义后实例化,最后才能调用。并且委托是类型安全的,它定义了返回类型和参数的类型,而在C/C++中,函数指针只是一个指向内存位置的指针,它不是类型安全的,我们无法判断这个指针实际指向什么,所以参数和返回类型等项就无法知道了。

定义委托

使用关键字delegate。语法类似于方法的定义,但没有方法体,定义的前面加上关键字delegate。

例如:定义一个委托:delegate void IntMethod(int x);

在这个示例中,定义了一个委托IntMethod,并指定该委托的每个实例都可以包含一个方法的引用,该方法带有一个int参数,返回类型为void。

如果要定义一个委托TwoLongOp,该委托表示的方法有两个long类型的参数,返回类型为double,则可以这样定义:delegate double TwoLongOp(long first,long second);

delegate  string GetString();//该委托表示的方法没有参数,返回string类型。

定义委托基本上是定义一个新类,可以在定义类的任何相同地方定义委托。也就是说可以在一个类的内部定义,也可以在外部定义,还可以在命名空间中把委托定义为顶层对象。

可以在委托的定义上应用访问修饰符:public,protected,private等,用来限定委托的作用域。例如:public delegate void IntMethod(int x);

实例化,调用

 1   private  delegate string GetString(int x);//定义委托
2 static void Main(string[] args)
3 {
4 GetString strMed = new GetString(StringMethod);//对委托进行实例化,并进行初始化
5 Console.WriteLine(strMed(555));//调用委托
6 Console.ReadKey();
7 }
8 private static string StringMethod(int x)
9 {
10 return x.ToString();
11 }

注意,在C#中,委托总是接受一个参数的构造函数,这个参数就是委托引用的方法,这个方法必须匹配委托定义时的签名。本例中委托定义时,返回类型为string,参数类型为int,所以初始化变量strMed时的方法StringMethod也必须与之一致。

类有两个不同的术语,“类”表示较广泛的定义,对象表示类的实例。但委托只有一个术语,在创建委托的实例时,所创建的委托实例仍称委托。

还可以直接把委托所引用的方法直接赋值给委托类型的变量(委托推断),例:  GetString strMed =StringMethod;

Action<T>和Func<T>委托

进一步简化了委托的定义,而不用显式声明自定义委托。

泛型Action<T>委托表示引用一个void返回类型的方法,这个委托类存在不同的变体,最多可传递16种不同的参数类型。没有泛型参数的Action类调用没有参数的方法。

public delegate void Action()      public delegate void Action<in T>(T obj)

......

 1    static void Main(string[] args)
2 {
3 Action<string> messageTarget;
4 messageTarget = GetAStr;
5 messageTarget("Action<T> Demo!");
6 Console.ReadKey();
7 }
8 private static void GetAStr(string obj)
9 {
10 Console.WriteLine(obj);
11 }

Func<T>允许调用带返回类型的方法,与Action<T>类似,也定义了不同的变体,最多也可传递16种不同的参数类型和一个返回类型。

public delegate TResult Func<out TResult>()

public delegate TResult Func<in T, out TResult>(T arg)

public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1,T2 arg2)      ......

 1  public static void Main()
2 {
3 Func<string, int, string[]> extractMethod = ExtractWords;//最后一个是返回值的类型,前面的都是参数的类型。
4 string str = "helloawordaFunc";
5 foreach (string word in extractMethod(str, 5))
6 Console.WriteLine(word);
7 }
8 private static string[] ExtractWords(string phrase, int limit)
9 {
10 char[] delimiters = new char[] { 'a' };
11 if (limit > 0)
12 return phrase.Split(delimiters, limit);
13 else
14 return phrase.Split(delimiters);
15 }

多播委托

一次委托调用多个方法,通过+和-运算符实现多播的增加或减少。多播委托包含已分配委托的列表。在调用多播委托时,它会按顺序调用列表中的委托。只能合并相同类型的委托。

 1     static void Main(string[] args)
2 {
3 Action del = D1;
4 del += D2;
5 del += D3;
6 del();
7 Console.WriteLine("------------------");
8 del -= D2;
9 del();
10 Console.ReadKey();
11 }
12 private static void D1()
13 {
14 Console.WriteLine("I am D1");
15 }
16 private static void D2()
17 {
18 Console.WriteLine("I am D2");
19 }
20 private static void D3()
21 {
22 Console.WriteLine("I am D3");
23 }

msdn上的例子:

 1   static void Hello(string s)
2 {
3 System.Console.WriteLine(" Hello, {0}!", s);
4 }
5 static void Goodbye(string s)
6 {
7 System.Console.WriteLine(" Goodbye, {0}!", s);
8 }
9 static void Main()
10 {
11
12 CustomDel hiDel, byeDel, multiDel, multiMinusHiDel;
13 hiDel = Hello;
14
15 byeDel = Goodbye;
16
17 multiDel = hiDel + byeDel;
18
19 multiMinusHiDel = multiDel - hiDel;
20
21 Console.WriteLine("Invoking delegate hiDel:");
22 hiDel("A");
23 Console.WriteLine("Invoking delegate byeDel:");
24 byeDel("B");
25 Console.WriteLine("Invoking delegate multiDel:");
26 multiDel("C");
27 Console.WriteLine("Invoking delegate multiMinusHiDel:");
28 multiMinusHiDel("D");
29 }

Lamada表达式和事件将在下篇中介绍。。。。

C#基础加强篇----委托、Lamada表达式和事件(上)的更多相关文章

  1. C#基础加强篇---委托、Lamada表达式和事件(中)

    2.Lamada表达式     C#共有两种匿名函数:匿名方法和Lamada表达式.在2.0之前的C#版本中,创建委托的唯一方法是使用命名方法.C#2.0中引入了匿名方法,匿名方法就是没有名称的方法. ...

  2. C#基础加强篇—委托、Lambda表达式和事件(下)

    3.事件 事件作为C#中的一种类型,为类和类的实例定义发出通知的能力,从而将事件和可执行代码捆绑在了一起.事件是对象发送的消息,以发信号通知操作的发生.操作可能是由用户交互引起的,也可能是由某些其他的 ...

  3. C#编程 委托 Lambda表达式和事件

    委托 如果我们要把方法当做参数来传递的话,就要用到委托.简单来说委托是一个类型,这个类型可以赋值一个方法的引用. 声明委托 在C#中使用一个类分两个阶段,首选定义这个类,告诉编译器这个类由什么字段和方 ...

  4. C#学习笔记三(委托·lambda表达式和事件,字符串和正则表达式,集合,特殊的集合)

    委托和事件的区别 序号 区别 委托 事件 1 是否可以使用=来赋值 是 否 2 是否可以在类外部进行调用 是 否 3 是否是一个类型 是 否,事件修饰的是一个对象 public delegate vo ...

  5. JS基础入门篇(二十)—事件对象以及案例(二)

    案例一.点击按钮,选中input中的全部内容 select()方法:选中全部. 点击按钮选中输入框中的内容!!!! <!DOCTYPE html> <html lang=" ...

  6. Linq学习工具及Lamada表达式

    好东西.转载一个.以备学习 Linq学习工具:     http://www.linqpad.net/ Lamada表达式: Func<int, int, int> IntPow = (x ...

  7. 第8章 委托、Lamdba表达式和事件

    本章内容: 委托    Lambda表达式 事件 8.1.3   简单的委托示例 首先定义一个类MathOperations,它有两个静态方法,对double类型的值执行两个操作. public cl ...

  8. C#基础篇——委托

    前言 在本章中,主要是借机这个C#基础篇的系列整理过去的学习笔记.归纳总结并更加理解透彻. 在.Net开发中,我们经常会遇到并使用过委托,如果能灵活的掌握并加以使用会使你在编程中游刃有余,然后对于很多 ...

  9. C# 篇基础知识5——委托和事件

    事件处理程序是基于“委托”机制运行的. 1.委托 (1)委托的定义和使用 有时需要将一个函数作为另一个函数的参数,这时就要用到委托(Delegate)机制.例如设计一个马戏表演函数: //定义委托 d ...

随机推荐

  1. 《TCP/IP具体解释卷2:实现》笔记--域和协议

    Net/3组把协议关联到一个域,而且用一个协议族常量来标识每一个域.Net/3还通过全部的编址方法将协议分组. 在一个域中 的每一个协议使用同类地址.而且每种地址仅仅被一个域使用.作为结果,一个域能通 ...

  2. 代码包结构分析工具JDepend的使用方法

    JDepend可以对Java软件包结构质量进行分析,已经有很多文章介绍其基本作用和能够计算的指标了,这里我就不详细总结,感兴趣的朋友可以参看如:http://blog.csdn.net/hantian ...

  3. 对raid几个技术的简单理解

    磁盘阵列(Redundant Arrays of Independent Disks,RAID),有“独立磁盘构成的具有冗余能力的阵列”之意,主要体现在两方面: 1.HA 高可用性,也就是冗余 2.L ...

  4. uva 116 Unidirectional TSP【号码塔+打印路径】

    主题: uva 116 Unidirectional TSP 意甲冠军:给定一个矩阵,当前格儿童值三个方向回格最小值和当前的和,就第一列的最小值并打印路径(同样则去字典序最小的). 分析:刚開始想错了 ...

  5. java-线程-生产者-消费者

    概述 在Java中有四种方法支持同步,其中前三个是同步方法,一个是管道方法. wait() / notify()方法 await() / signal()方法 BlockingQueue阻塞队列方法 ...

  6. 一道SQL题考你数据库的使用能力

    题目:数据库中存在例如以下数据,求用户终于剩余金额. 用户 类型 金额 A 存入 100 A 存入 200 A 取出 100 A 取出 200 A 存入 300 A 取出 300 本人Oracle接触 ...

  7. Qt写入unicode编码格式的文本(用QChar写入BOM标记,并且列出所有Qt支持的字符集)

    1.文本流设置unicode小端模式 2.写入文本前两个字节FF FE 3.字符串转成unicode编码 QList<QByteArray> list = QTextCodec::avai ...

  8. Spring boot传统部署

    使用spring boot很方便,一个jar包就可以启动了,因为它里面内嵌了tomcat等服务器. 但是spring boot也提供了部署到独立服务器的方法. 如果你看文档的话,从jar转换为war包 ...

  9. URLDecoder和URLEncoder的使用总结

    其实,这两个类的使用并不复杂,URLDecoder和URLEncoder它的作用主要是用于普通字符串和application/x-www-form-rulencoded MIME字符串之间的转换,一般 ...

  10. 链接hdf5库出现错误的解决办法

    作者:朱金灿 来源:http://blog.csdn.net/clever101 在链接hdf5库出现一些链接错误: error LNK2001: 无法解析的外部符号 _H5T_NATIVE_DOUB ...