1.为什么要使用委托?

生活中的委托就是委托他人帮我们去办一件事情,程序中的委托类似。看下面的例子

    class Class1
{
static void Main(String[] args)
{
List<int> list = new List<int>();
list.Add();
list.Add();
list.Add();
list.Add();
list.Add(); //过滤偶数
Even(list); ObjectDumper.Write(list);
} //过滤集合中的偶数
public static void Even(List<int> list)
{
for (int i = ; i < list.Count; i++)
{
if (list[i] % 2 != )
{
list.RemoveAt(i);
i--;
}
}
} //过滤集合中的奇数
public static void Odd(List<int> list)
{
for (int i = ; i < list.Count; i++)
{
if (list[i] % 2 == )
{
list.RemoveAt(i);
i--;
}
}
}
}

通过上面的例子我们发现 Even()方法 和 Odd()方法只有一行代码不同,使用委托可以将方法当成参数传递,这样做的好处是使程序之间的耦合降低,同时节省代码。

改造上面的代码如下:

   class Class2
{
//声明委托
public delegate bool Cal(int num);
static void Main(String[] args)
{
List<int> list = new List<int>();
list.Add();
list.Add();
list.Add();
list.Add();
list.Add(); //过滤偶数
Cal cal = new Cal(Even);
MyCal(list, cal); ObjectDumper.Write(list);
} public static bool Even(int num)
{
if (num % == )
{
return true;
}
return false;
}
public static bool Odd(int num)
{
if (num % != )
{
return true;
}
return false;
} public static void MyCal(List<int> list,Cal cal)
{
for (int i = ; i < list.Count; i++)
{
if (cal(list[i]))
{
list.RemoveAt(i);
i--;
}
}
} }

委托描述的是方法的签名(包括参数类型、个数、返回值),上面声明一个委托 Cal ,和 我们要调用的方法一样,接收一个 int类型的参数,返回bool类型。

public delegate bool Cal(int num);

使用New关键字创建委托:

Cal cal = new Cal(Even);

最后调用cal,得到所有偶数项的集合

MyCal(list, cal);

我们在 MyCal(List<int> list,Cal cal) 方法中,传递了一个委托 作为参数,Cal描述的是 Even 或者Odd方法的签名,这样可以在调用的时候决定 是过滤奇数 还是 过滤偶数。

这和我们直接调用Even或Odd方法有什么不同,不是更麻烦了吗,接着往下看:

我们可以将过滤的方法改成如下代码:

MyCal(list, delegate(int i)
{
if (i % == )
{
return true;
}
return false;
});

正因为MyCal方法接收的是一个委托,所以我们可以在不定义Even或Odd的时候,使用匿名委托。

这样省去了不必要的代码,使结构看起来更简单,也不需要预先定义好方法,在调用的时候我们临时决定。

.NET 还给我们提供了更进一步的简化,使用Lambda表达式:

//代码演进
//lamada
MyCal(list, (i) => { return i % == ? true : false; });

i表示输入参数 (i) => { return i % 2 == 0 ? true : false; } 是一条lambda语句,标识过滤偶数。

完整的代码如下:

//声明委托
public delegate bool Cal(int num);
static void Main(String[] args)
{
List<int> list = new List<int>();
list.Add();
list.Add();
list.Add();
list.Add();
list.Add(); MyCal(list, (i) => { return i % 2 == 0 ? true : false; }); ObjectDumper.Write(list);
} public static void MyCal(List<int> list, Cal cal)
{
for (int i = ; i < list.Count; i++)
{
if (cal(list[i]))
{
list.RemoveAt(i);
i--;
}
}
}

这样做是不是比开始的时候简单多了,无论后面再怎么添加新的过滤方式,我们只需要修改我们的lambda语句,其他的都不需要变动,这就是委托的魅力。

.NET (一)委托第一讲:什么是委托的更多相关文章

  1. c#委托事件入门--第一讲:委托入门

    说起委托,有些刚刚入门c#的人感觉很高大上,没有接触过,但是其实很多人都用过Lambda表达式,实际上Lambda表达式就是一个委托. 关于委托入门有个大神写的很详细:张子阳的博客  C#中的委托和事 ...

  2. 第一章、C#委托和事件(Delegate、Event、EventHandler、EventArgs)

    第一章.C#委托和事件(Delegate.Event.EventHandler.EventArgs) 分类: 学习笔记-C#网络编程2012-12-08 14:10 7417人阅读 评论(3) 收藏  ...

  3. C#_基础:委托速讲

    1定义:委托=函数指针 C# public delegate void Test(string str); 等价C++ public void (*Test)(string str): 委托赋值(初始 ...

  4. 链方法[C# 基础知识系列]专题三:如何用委托包装多个方法——委托链

    最近研究链方法,稍微总结一下,以后继续补充: 弁言: 上一专题分析了下编译器是如何来翻译委托的,从中间语言的角度去看委托,希望可以帮助大家进一步的理解委托,然而之前的分析都是委托只是封装一个方法,那委 ...

  5. [C# 基础知识系列]专题三:如何用委托包装多个方法——委托链 (转载)

    引言: 上一专题介绍了下编译器是如何来翻译委托的,从中间语言的角度去看委托,希望可以帮助大家进一步的理解委托,然而之前的介绍都是委托只是封装一个方法,那委托能不能封装多个方法呢?因为生活中经常会听到, ...

  6. 自定义委托类型 - .Net自带委托类型

    委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递. 与其他的类不同,委托类具有一个签名,并且它只能对与其签名匹配的方法进行引用. 一.自定义委托类型 1.语法结构:访问修 ...

  7. CS193P - 2016年秋 第一讲 课程简介

    Stanford 的 CS193P 课程可能是最好的 ios 入门开发视频了.iOS 更新很快,这个课程的最新内容也通常是一年以内发布的. 最新的课程发布于2016年春季.目前可以通过 iTunes ...

  8. POI教程之第一讲:创建新工作簿, Sheet 页,创建单元格

    第一讲 Poi 简介 Apache POI 是Apache 软件基金会的开放源码函数库,Poi提供API给java程序对Microsoft Office格式档案读和写的功能. 1.创建新工作簿,并给工 ...

  9. 《ArcGIS Engine+C#实例开发教程》第一讲桌面GIS应用程序框架的建立

    原文:<ArcGIS Engine+C#实例开发教程>第一讲桌面GIS应用程序框架的建立 摘要:本讲主要是使用MapControl.PageLayoutControl.ToolbarCon ...

随机推荐

  1. liunx之:解决liunx下dns配置重启失效的问题

    有时候能ping同ip地址,却ping不通域名,这就是dns没有配置的缘故. 但是DNS配置文件 /etc/resolv.conf 每次重启就会失效. 打开这个配置文件,发现有注释提示: Dynami ...

  2. OpenGL变换

    概述 OpenGL变换矩阵 实例:GL_MODELVIEW矩阵 实例:GL_PROJECTION矩阵 概述 OpenGL管线中,在光栅化操作之前,包括顶点位置与法线向量的几何数据经顶点操作与图元装配操 ...

  3. CentOS 7下源码安装MySQL 5.6

    本文转载,并非原创. 目录 准备工作 运行环境 确认你的安装版本 下载MySQL 安装MySQL 准备安装环境 编译和安装 配置MySQL 单实例配置 单实例配置方法 添加防火墙 启动MySQL 重启 ...

  4. SCRIPT7002: XMLHttpRequest: 网络错误 0x2ef3, 由于出现错误 00002ef3 而导致此项操作无法完成,浏览器中的Keep-Alive

    http://www.cnblogs.com/OpenCoder/p/5089258.html     IE中Keep-Alive机制引起的错误 我们知道Http协议是基于TCP/IP连接的,也就是说 ...

  5. Mysql-cluster7.5

    Data nodes: shell> rpm -Uhv mysql-cluster-community-data-node-7.5.5-1.1.el7.x86_64.rpm SQL nodes: ...

  6. php自学提升进阶路线

    为了自己对php的系统全面深入的掌握,我通过个人经验,以及搜索网上高手经验,汇总了一份php自我学习路线规划,包括实战演练.学习建议.高手进阶.常见问题和测试总结五块.算是一个系统的学习计划和目标吧. ...

  7. C# ListView用法详解

    一.ListView类 1.常用的基本属性: (1)FullRowSelect:设置是否行选择模式.(默认为false) 提示:只有在Details视图该属性才有意义. (2) GridLines:设 ...

  8. Spring事务配置的五种方式

    Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource.TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分. DataSo ...

  9. WeX5 - AJAX跨域调用相关知识-CORS和JSONP

    http://docs.wex5.com/ajax-cross-domain/ 1.什么是跨域 跨域问题产生的原因,是由于浏览器的安全机制,JS只能访问与所在页面同一个域(相同协议.域名.端口)的内容 ...

  10. Hadoop总结篇之五---模块间是怎么驱动执行的

    在MRv1中,各个模块间驱动运行的方式是函数调用的方式.这是同步的过程,上一模块调用下一模块函数后,等待其执行.效率不高. 在MRv2中做了改进,yarn基于事件驱动的并发模型.在详细介绍前,先看下图 ...