委托常常和事件在一起使用,可以理解委托是方法的容器,事件则是委托的另一种表现形式。委托和事件虽然写得还比较多,不过也只是用的熟练而已,趁周末没课好好巩固下基础,一点一点积累吧。

1.一个简单的小例子

    class Program
{
static void Main(string[] args)
{
People people = new People();
people.StartEat("吃");
Console.ReadLine();
}
}
class People
{
public void EatApple(string s)
{
Console.WriteLine(s+"苹果");
}
public void EatPear(string s)
{
Console.WriteLine(s+"梨子");
}
public void StartEat(string str)
{
EatApple(str);
}
}

上面的代码应该很好理解,但是在StartEat方法并不知道什么时候该调用哪个方法进行输出,因此在调用之前还需要定义一个枚举EatWhat来进行判断,也就是StartEat(string str,EatWhat eatWhat)。传入的eatWhat枚举判断是吃苹果还是梨子。但是这种写法扩展性太差了,如果再加一个吃西瓜的方法,那么还要更新枚举,这样反复的增加方法和枚举显然不是一个很好的做法。

  显然这里要使用委托,为什么要使用委托?最本质的原因是利用委托可使StartEat得到一个参数,而这个参数是方法,这样我们想调用什么就可以调用什么了。

class Program
{
static void Main(string[] args)
{
People people = new People();
people.StartEat("吃", people.EatApple);
people.StartEat("吃", people.EatPear);
Console.ReadLine();
}
}
public delegate void EatDelegate(string name);
class People
{
public void EatApple(string s)
{
Console.WriteLine(s+"苹果");
}
public void EatPear(string s)
{
Console.WriteLine(s + "梨子");
}
public void StartEat(string str,EatDelegate eatDelegate)
{
eatDelegate(str);
} }

2.多播委托

  委托的特殊之处在于,我们以前定义的所有对象都包含数据,而委托包含的只是方法的地址。在上面例子的基础上,我们还可以实现多播委托。多播委托就是讲多个方法赋给同一个委托,当调用这个委托的时候,将依次调用其绑定的方法。下面是对Program类的改动。

    class Program
{
static void Main(string[] args)
{
People people = new People();
EatDelegate del = people.EatPear;
del += people.EatApple;
people.StartEat("吃", del);
//既然可以对委托添加方法,那么也可以对委托取消方法的绑定
del -= people.EatPear;
Console.ReadLine();
}
}

 3.委托和事件

  在上面的例子中,我们给StartEat方法传参时需要传入2个参数,而且还需要在Main方法中得到委托对象。因此我们可以将委托封装到People类里面,使传参时只传入一个参数,这就是用到了封装的思想。

 class Program
{
static void Main(string[] args)
{
People people = new People();
people.del = people.EatPear;
people.del += people.EatApple;
people.StartEat("吃");
Console.ReadLine();
}
}
class People
{
public EatDelegate del;
public void EatApple(string s)
{
Console.WriteLine(s+"苹果");
}
public void EatPear(string s)
{
Console.WriteLine(s + "梨子");
}
public void StartEat(string str)
{
if (del != null)
{
del(str);
}
}
}

现在我们的委托对象和一般的变量没有什么区别,外部类访问到People对象就可以拿到这个委托变量。假如现在在类里面声明一个字段,一般我们会封装字段采用属性。同样的,对于委托我们也要封装,这样在类的内部,委托变量总是私有,但是在外部,依旧可以使用+=和-=的访问操作。接下来我们对代码进行改写。

 static void Main(string[] args)
{
People people = new People();
//现在已经不能使用=来给事件对象赋值,而只能使用+=和-=来进行操作
people.eventDelegate += people.EatApple;
people.eventDelegate+=people.EatPear;
people.StartEat("吃");
Console.ReadLine();
}
}
class People
{
//简单点理解,事件其实就可以理解为一个封装了委托的变量
//如果去看代码执行的源码,会发现eventDelegate变量,其实就是一个委托对象,只不过它是私有的,修饰符为private
//这个委托变量有2个方法 ,且只有2个方法,+=对应addon,-=对应于removeon方法。
public event EatDelegate eventDelegate;
public void EatApple(string s)
{
Console.WriteLine(s+"苹果");
}
public void EatPear(string s)
{
Console.WriteLine(s + "梨子");
}
public void StartEat(string str)
{
eventDelegate(str);
}
}

C#基础之委托的更多相关文章

  1. C#基础系列——委托和设计模式(二)

    前言:前篇 C#基础系列——委托实现简单设计模式 简单介绍了下委托的定义及简单用法.这篇打算从设计模式的角度去解析下委托的使用.我们知道使用委托可以实现对象行为(方法)的动态绑定,从而提高设计的灵活性 ...

  2. [.net 面向对象编程基础] (21) 委托

    [.net 面向对象编程基础] (20)  委托 上节在讲到LINQ的匿名方法中说到了委托,不过比较简单,没了解清楚没关系,这节中会详细说明委托. 1. 什么是委托? 学习委托,我想说,学会了就感觉简 ...

  3. 转载 【.NET基础】--委托、事件、线程(2) https://www.cnblogs.com/chengzish/p/4569912.html

    [.NET基础]--委托.事件.线程(2)   本文介绍event的使用以及原理,本文接上一篇文章的Demo继续[下载上一篇Demo] 上一篇我们在类(dg_SayHi.cs)里面定义代理了4个Del ...

  4. 转载 【.NET基础】--委托、事件、线程(1) https://www.cnblogs.com/chengzish/p/4559268.html

    [.NET基础]--委托.事件.线程(1)   1,委托 是存放方法的指针的清单,也就是装方法的容器 A, 新建winform项目[01委托],项目中添加dg_SayHi.cs 委托类 用于存储方法 ...

  5. C#基础系列——委托实现简单设计模式

    前言:上一篇介绍了下多线程的相关知识:C#基础系列——多线程的常见用法详解,里面就提到了委托变量.这篇简单介绍下委托的使用.当然啦,园子里面很多介绍委托的文章都会说道:委托和事件的概念就像一道坎,过了 ...

  6. [C#基础]说说委托+=和-=的那些事

    写在前面 为什么会突然想说说委托?原因吗,起于一个同事的想法,昨天下班的路上一直在想这个问题,如果给委托注册多个方法,会不会都执行呢?为了一探究性,就弄了个demo研究下. += 大家都知道委托都继承 ...

  7. 【.NET基础】--委托、事件、线程(3)

    之前的两篇文章我们了解了委托和事件,本文我们看一下线程. 1,一个窗体程序,默认拥有一个线程(相当于一个商店里面,只有一个店员),这个默认的线程叫做 UI线程/主线程. 2,进程和线程的关系: A,进 ...

  8. 转载 【.NET基础】--委托、事件、线程(3)

      之前的两篇文章我们了解了委托和事件,本文我们看一下线程. 1,一个窗体程序,默认拥有一个线程(相当于一个商店里面,只有一个店员),这个默认的线程叫做 UI线程/主线程. 2,进程和线程的关系: A ...

  9. C#基础篇——委托

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

随机推荐

  1. 寄存器简介 与 ebp esp

    http://www.cnblogs.com/zhuyuanhao/archive/2012/10/16/3262870.html 32位CPU所含有的寄存器有:4个数据寄存器(EAX.EBX.ECX ...

  2. Python 模块化 from .. import 语句资源搜索顺序 (三)

    接着上一篇文章最后的import子句资源搜索顺序,我们来写几个例子了解下. 例一. #test1.py x = 123 #test.py import test1 print(dir()) print ...

  3. leaflet 中文API

    LeafLet js 官网:http://leafletjs.com/index.html LeafLet js 官网demo: http://leafletjs.com/examples.html ...

  4. [LuoguP1221]最多因子数

    [Luogu1221]最多因子数(Link) 求区间[L,R]内约数个数最多的数和它的约数个数. 这个题吧,乍一看确实不是很难,然后稍微一想,嗯,是个傻*题.这是唯一感受,不要问我为什么. 首先我们定 ...

  5. ovs的卸载删除

    参考博客1 参考博客2 需要更新.重装ovs时需要先卸载. 删除网桥.端口 ovs-vsctl del-br 交换机名 ovs-vsctl del-port 交换机名 端口名(网卡名) 关闭服务 su ...

  6. 我的QT5学习之路(二)——第一个程序

    一.前言 “工欲善其事,必先利其器”,上一节,我介绍了Qt的安装和配置方法,搭建了基本的开发平台.这一节,来通过一个简单的例子来了解Qt的编程样式和规范,开始喽~~~ 二.第一个程序——Hello W ...

  7. Spring coud微服务框架具体实现关键说明

    搭建一个微服务,考虑的问题涉及到运维,数据管理,性能,并发等方方面面.项目中使用Spring coud 搭建微服务,从技术选型,到技术实现都要全方面考虑服务化的问题.下面简单总结下搭建过程用的技术说明 ...

  8. iOS audio不支持循环播放

    解决办法:监听播放完成事件(注意点,audio标签不能设置循环播放,去除标签 loop="loop"或者 loop="false",不然不走播放完成事件) $( ...

  9. K8S学习心得 == 创建容器influxdb的RC和SVC

    附上:YAML在线检查:http://nodeca.github.io/js-yaml Part 1: 部署Influxdb的RC文件,步骤如下: step 1: influxdb-rc.yaml文件 ...

  10. jar下载地址

    java开发难免需要下载额外的jar,推荐一个地址 http://www.java2s.com/Code/Jar/CatalogJar.htm