前言:

C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针。委托是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。委托(Delegate)特别用于实现事件和回调方法。所有的委托都派生自 System.Delegate 类。把一个方法当作参数传递,让其它方法进行调用执行。

1.委托的声明

委托声明决定了可由该委托引用的方法。委托可指向一个与其具有相同标签的方法。

1.1.delegate

1.1.1. 0-23个参数,可以有返回值也可以没有返回值

public delegate int MyDelegateEventHandler (string parm);

注:(1).此委托指向的方法必须是参数为string类型,返回类型为int类型的。其他声明类比所得。

  (2).EventHandler是c# 命名规范,当然我理解规范就是可以随意啦。

(3).委托调用时必须判断是否为null不然会报异常

(4).事件也是一种委托

1.1.2.委托的调用

MyDelegateEventHandler fun=new MyDelegateEventHandler(method);
or
MyDelegateEventHandler fun=method;
// fun不为空,则调用回调方法
if (fun!= null)
{
fun(val);
}
//fun?.Invoke(val); 简化版本调用

1.1.3.委托的多播

每个委托都只包含一个方法调用,如果调用多个方法,就需要多次显示调用这个委托。如果同一个委托调用多个方法,我们就可以用多播委托

public delegate void MyDelegate ();

public voidMyMethod()
{
//#
}
public void MyMethod1()
{
//#
}
public void MyMethod2()
{
//#
}
MyDelegateEnventHander myDelegate;
myDelegate=new MyDelegateEventHander(MyMethod);
myDelegate+=new MyDelegateEventHander(MyMethod1);
...........
//调用
myDelegate();

注:

  1.委托对象可使用 "+" 运算符进行合并;

  2."-" 运算符可用于从合并的委托中移除组件委托;

  3.委托指定方法类型必须一致;

  4.返回类型一般为void,但非必须;

  5.GetInvocationList获取委托索引

if (MyDelegate != null)
System.Delegate[] dels = MyDelegate .GetInvocationList();
for (int i = ; i < dels.Length; i++)
  {
MyDelegate -= dels[i] as MethodDelegate;
  }

以上是利用GetInvocationList获取委托索引的一个简单应用。

1.2.Action

Action至少0个参数,至多16个参数,无返回值。

Action 表示无参,无返回值的委托
Action<int,string> 表示有传入参数int,string无返回值的委托
Action<int,string,bool> 表示有传入参数int,string,bool无返回值的委托
Action<int,int,int,int> 表示有传入4个int型参数,无返回值的委托
 public void Test<T>(Action<T> action,T p)
{
action(p);
}

1.3.Func

Func至少0个参数,至多16个参数,根据返回值泛型返回。必须有返回值,不可void

Func是无返回值的泛型委托
Func<int> 表示无参,返回值为int的委托
Func<object,string,int> 表示传入参数为object, string 返回值为int的委托
Func<object,string,int> 表示传入参数为object, string 返回值为int的委托
Func<T1,T2,,T3,int> 表示传入参数为T1,T2,,T3(泛型)返回值为int的委托

1.4.predicate

1.4.1.predicate 是返回bool型的泛型委托;

1.4.2.predicate<int> 表示传入参数为int 返回bool的委托;

1.4.3.Predicate有且只有一个参数,返回值固定为bool;

public delegate bool Predicate<T> (T obj)

2.委托的实例化

2.1.delegate

public delegate int MyDelegateEventHandler (string parm)
public int MyMethod(string parm)
{
//#
}
MyDelegateEventHandler MyDelegate=new MyDelegateEventHandler(MyMethod)

注:委托实例化的时候,委托对象必须使用 new 关键字来创建,且与一个特定的方法有关。委托参数中的方法不含参数。

2.2.Action的使用

 public void Test<T>(Action<T> action, T p)
{
action(p);
}
private void Action(string s)
{
#
}
//调用
Test<string>(Action,"wyl");

2.3.Func的使用

public int Test<T1, T2>(Func<T1, T2, int> func, T1 a, T2 b)
{
return func(a, b);
}
private int Fun(int a, int b)
{
#
}
//调用
Test<int,int>(Fun,,)

2.4 委托实现冒泡排序

//定义对象
class Student
{
public string Name { get; private set; }
public decimal Scores{ get; private set; } public Student(string name, decimal scores)
{
this.Name = name; this.Scores= scores;
}
public override string ToString()
{
return string.Format("{0},{1:C}",Name,Scores);
}
public static bool CompareScores(Student e1,Student e2)
{
return e1.Scores< e2.Scores;
}
}
//利用委托实现冒泡
class BubbleScores
{
public static void Sort<T>(IList<T> sortArray, Func<T, T, bool> comparison)
{
bool swapped = true;
do
{
swapped = false;
for (int i = ; i < sortArray.Count - ; i++)
{
if (comparison(sortArray[i + ], sortArray[i]))
{
T temp = sortArray[i];
sortArray[i] = sortArray[i + ];
sortArray[i + ] = temp;
swapped = true;
}
}
} while (swapped);
}
}
//调用
Student[] students={new Student("wyl", ),#};
BubbleSorter.Sort(students, Student.CompareScores);
foreach(var student in students)
Console.WriteLine(student);

3.匿名函数与lambda

3.1什么是匿名函数

匿名函数是一个“内联”语句或表达式,可在需要委托类型的任何地方使用。

可以使用匿名函数来初始化命名委托(无需取名字的委托),或传递命名委托(而不是命名委托类型,传递一个方法块,而不是委托类型)[callback的方式]作为方法参数。

MyDelegate funDelegate = delegate(string s) { Console.WriteLine(s); };
funDelegate ("this is anonymous delegate");

3.2.lambda

lambda表达式实际上是一个匿名函数。编译器在看到lambda之后会在类中自动定义一个新的私有方法。lambda必须匹配委托!其中lambda是从c#3.0后引用的

lambda的语法:

参数 => 方法体。

=>左边是要传入的参数,本例中是传入一个Int类型的变量,=>右边是具体的代码。

//如果不传递参数:
()=>Console.WriteLine("Hello World!")
//传递一个参数:
(int n)=>Console.WriteLine(n.ToString())
//或者去掉()和int 编译器会自己推断类型:
n=>Console.WriteLine(n.ToString())
//传递多个参数:
(int n ,int m)=>Console.WriteLine(n+m)
//或者编译器自己推断类型:
(n , m)=>Console.WriteLine(m+n)

4.综上:

4.1.委托类似于 C++ 函数指针。

4.2.委托允许将方法作为参数进行传递。

4.3.委托可用于定义回调方法。

4.4.委托可以链接在一起;多播。

4.5.方法不必与委托签名完全匹配。

作者:王延领

出处:http://wyl1924.cnblogs.com

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

基础拾遗---委托,匿名函数,lambda的更多相关文章

  1. 【Unity|C#】基础篇(9)——匿名函数 / Lambda表达式

    [学习资料] <C#图解教程>(第13章):https://www.cnblogs.com/moonache/p/7687551.html 电子书下载:https://pan.baidu. ...

  2. 『Python基础-14』匿名函数 `lambda`

    匿名函数和关键字lambda 匿名函数就是没有名称的函数,也就是不再使用def语句定义的函数 在Python中,如果要声匿名函数,则需要使用lambda关键字 使用lambda声明的匿名函数能接收任何 ...

  3. (28)C#委托,匿名函数,lambda表达式,事件

    一.委托 委托是一种用于封装命名和匿名方法的引用类型. 把方法当参数,传给另一个方法(这么说好理解,但实际上方法不能当参数,传入的是委托类型),委托是一种引用类型,委托里包含很多方法的引用 创建的方法 ...

  4. python3 速查参考- python基础 6 -> 函数编程之参数、变量、作用域、递归、匿名函数 lambda

    函数基础 1. 速查笔记 #-- 函数相关的语句和表达式 myfunc('spam') # 函数调用 def myfunc(): # 函数定义 return None # 函数返回值 global a ...

  5. 内置函数filter()和匿名函数lambda解析

    一.内置函数filter filter()函数是 Python 内置的一个高阶函数,filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回由符合条件迭代器 ...

  6. python--函数式编程 (高阶函数(map , reduce ,filter,sorted),匿名函数(lambda))

    1.1函数式编程 面向过程编程:我们通过把大段代码拆成函数,通过一层一层的函数,可以把复杂的任务分解成简单的任务,这种一步一步的分解可以称之为面向过程的程序设计.函数就是面向过程的程序设计的基本单元. ...

  7. python的匿名函数lambda解释及用法

    lambda函数的语法只包含一个语句,如下:    lambda arg1,arg2,.....argn:expression(主要是看下面的例子)代码示例: #-*- coding:utf-8 -* ...

  8. 匿名函数lambda,过滤函数filter,映射类型map

    匿名函数lambda, 作用是不用定义函数,用完之后会自动被删掉,在使用执行脚本的时候,使用lambda就可以省下定义函数的过程,简化代码的可读性. 格式是 例子g=lambda x,y:x+y g( ...

  9. 6.1 函数的返回值、匿名函数lambda、filter函数、map函数、reduce函数

      函数的返回值: 函数一旦执行到   return,函数就会结束,并会返回return 后面的值,如果不使用显式使用return返回,会默认返回None . return None可以简写为   r ...

  10. python的匿名函数 lambda的使用方法详解以及使用案例

    1.匿名函数是用lambda这个关键字定义 lambda  x:x+1   第一个x代表形参,x+1相当于函数的返回值 #lambda x:x+1 第一个x代表形参,x+1相当于函数的返回值 def ...

随机推荐

  1. vue使用stylus样式预处理器

    vue使用stylus样式预处理器,样式总是报错,需要从上一行的样式回车换行才不会报错 <style lang="stylus" scoped> .navbar mar ...

  2. Golang源码学习:调度逻辑(二)main goroutine的创建

    接上一篇继续分析一下runtime.newproc方法. 函数签名 newproc函数的签名为 newproc(siz int32, fn *funcval) siz是传入的参数大小(不是个数):fn ...

  3. {dede:channelartlist} 改变偶数的class

    {dede:channelartlist} <div {dede:global.itemindex runphp='yes'} if((@me %2) == 0){ @me = 'class=& ...

  4. Consul+upsync+Nginx实现动态负载均衡

    上一篇文章 <C# HttpClient 使用 Consul 发现服务> 解决了内部服务之间的调用问题, 对外提供网关服务还没有解决, 最后我选择了 nginx-upsync-module ...

  5. [FlashDevelop] 003.FlashDevelop + LayaFlash + Starling环境配置及实战

    1.首先我们需要下载LayaStarling框架地址:http://layabox.com/index.php?m=content&c=index&a=lists&catid= ...

  6. (八)Filter&ThreadLocal实现处理事务

    ConnectionContext.java package com.aff.bookstore.web; import java.sql.Connection; public class Conne ...

  7. 创建并加入节点&练习

    1.节点的属性 节点的属性:所有节点都有的属性 元素节点,   属性节点,   文本节点 nodeType            只  读  属  性 nodeName       返回对应节点的名字 ...

  8. matlab单目相机标定——标定步骤以及参数含义

    参考博客园的一篇文章: https://www.cnblogs.com/flyinggod/p/8470407.html#commentform

  9. 小谢第10问:前端JS下载文件、表格

    对于小型文件及表格下载,一般采用a标签形式 <buttonb @click="downloadTemplate()">模板下载</button> downl ...

  10. SpringBoot学习笔记(十五:OAuth2 )

    @ 目录 一.OAuth 简介 1.什么是OAuth 2.OAuth 角色 3.OAuth 授权流程 4.OAuth授权模式 4.1.授权码 4.2.隐藏式 4.3.密码式 4.4.凭证式 二.实践 ...