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

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表达式和事件将在下篇中介绍。。。。

时间: 2024-12-14 17:13:44

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

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

2.Lamada表达式     C#共有两种匿名函数:匿名方法和Lamada表达式.在2.0之前的C#版本中,创建委托的唯一方法是使用命名方法.C#2.0中引入了匿名方法,匿名方法就是没有名称的方法.从C#3.0开始,就可以使用一种新语法把实现代码赋予委托——Lamada表达式. 在了解Lamada表达式之前,我们先来了解一下匿名方法.用匿名方法定义委托的语法与之前的没有区别,但在实例化时就有了一些区别. 使用命名方法创建的委托 1 class Program 2 { 3 private del

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

3.事件 事件作为C#中的一种类型,为类和类的实例定义发出通知的能力,从而将事件和可执行代码捆绑在了一起.事件是对象发送的消息,以发信号通知操作的发生.操作可能是由用户交互引起的,也可能是由某些其他的程序逻辑触发的.引发(触发)事件的对象叫做事件发送方,捕获事件并对其做出响应的对象叫做事件接收方. C#事件是按“发布——预定”的方式工作.先在一个类中公布事件,然后就可以在任意数量的类中对事件预定.在事件通信中,事件发送方类并不知道哪个对象或方法将接收到(处理)它所引发的事件.所需要的是在源和接收

【音视频连载-007】基础学习篇-SDL 播放 PCM 音频文件(上)

音视频学习入门技术文章连载: 技术开发故事会连载 [音视频连载-001]基础学习篇-SDL 介绍以及工程配置 [音视频连载-002]基础学习篇-SDL 创建窗口并显示颜色 [音视频连载-003]基础学习篇-SDL 消息循环和事件响应 [音视频连载-004]基础学习篇-SDL 加载图片并显示 [音视频连载-005]基础学习篇-SDL 加载 YUV 文件并显示 [音视频连载-006]基础学习篇-SDL 播放 YUV 视频文件]) 在前面的文章中已经能够利用 SDL 去播放 YUV 视频文件了,接下来

ASP.NET MVC学前篇之Lambda表达式、依赖倒置

前言 随着上篇文章的阅读,可能有的朋友会有疑问,比如(A.Method(xxx=>xx>yy);)类似于这样的函数调用语句,里面的xxx=>xx>yy这些到底是怎么用的? 依赖倒置原则的实现也会在本篇幅的最后来粗略的讲解一下. 本篇没有核心的主题,如果说要强制定义的话就是这些内容都是基础知识,是为了后续学习MVC框架做铺垫. 1 Lambda Lambda表达式在日常的开发中很常见,使用Lambda表达式可以自由的定义函数体并且精简代码量,那么Lambda表达式是什么呢? Lamb

五分钟重温C#委托,匿名方法,Lambda,泛型委托,表达式树

五分钟重温C#委托,匿名方法,Lambda,泛型委托,表达式树 https://masuit.com/81 曾经新生代,好多都经过漫长的学习,理解,实践才能掌握委托,表达式树这些应用.今天我尝试用简单的方法叙述一下,让大家在五分钟内看完这篇博客 第一分钟:委托 有些教材,博客说到委托都会提到事件,虽然事件是委托的一个实例,但是为了理解起来更简单,今天只谈委托不谈事件.先上一段代码: 下边的代码,完成了一个委托应用的演示.一个委托分三个步骤: 1 2 3 4 5 6 7 8 9 10 11 12

C#基础知识篇(二)-----------C#笔记

1.关系运算符(比较运算符) 1.关系运算符有哪些? >,< ==,!= >=,<= 2.关系运算符的作用? 用于比较两个事物之间的关系. 3.什么叫关系表达式? 由关系运算符连接起来的式子叫关系表达式. 注意:所有的关系表达式最终都能计算成一个bool类型的值. 2.逻辑运算符 1.逻辑表达式有哪些? 逻辑与:&& ,逻辑或:||  ,逻辑非:!(又叫取反) 2.逻辑运算 语法:表达式1 逻辑运算符  表达式2 逻辑运算符连接的两个表达式,要最终能求解成一个boo

基础很重要~~04.表表达式-上篇

以前总是追求新东西,发现基础才是最重要的,今年主要的目标是精通SQL查询和SQL性能优化. 本系列[T-SQL基础]主要是针对T-SQL基础的总结. [T-SQL基础]01.单表查询-几道sql查询题 [T-SQL基础]02.联接查询 [T-SQL基础]03.子查询 [T-SQL基础]04.表表达式-上篇 [T-SQL基础]04.表表达式-下篇 [T-SQL基础]05.集合运算 [T-SQL基础]06.透视.逆透视.分组集 [T-SQL基础]07.数据修改 [T-SQL基础]08.事务和并发 [

基础很重要~~04.表表达式

阅读目录 概述: 一.视图 二.内联表值函数 三.APPLY运算符 以前总是追求新东西,发现基础才是最重要的,今年主要的目标是精通SQL查询和SQL性能优化. 本系列[T-SQL基础]主要是针对T-SQL基础的总结. [T-SQL基础]01.单表查询-几道sql查询题 [T-SQL基础]02.联接查询 [T-SQL基础]03.子查询 [T-SQL基础]04.表表达式-上篇 [T-SQL基础]04.表表达式-下篇 [T-SQL基础]05.集合运算 [T-SQL基础]06.透视.逆透视.分组集 [T

基础很重要~~04.表表达式-下篇

以前总是追求新东西,发现基础才是最重要的,今年主要的目标是精通SQL查询和SQL性能优化. 本系列[T-SQL基础]主要是针对T-SQL基础的总结. [T-SQL基础]01.单表查询-几道sql查询题 [T-SQL基础]02.联接查询 [T-SQL基础]03.子查询 [T-SQL基础]04.表表达式-上篇 [T-SQL基础]04.表表达式-下篇 [T-SQL基础]05.集合运算 [T-SQL基础]06.透视.逆透视.分组集 [T-SQL基础]07.数据修改 [T-SQL基础]08.事务和并发 [