C#基础之委托
委托常常和事件在一起使用,可以理解委托是方法的容器,事件则是委托的另一种表现形式。委托和事件虽然写得还比较多,不过也只是用的熟练而已,趁周末没课好好巩固下基础,一点一点积累吧。
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#基础之委托的更多相关文章
- C#基础系列——委托和设计模式(二)
前言:前篇 C#基础系列——委托实现简单设计模式 简单介绍了下委托的定义及简单用法.这篇打算从设计模式的角度去解析下委托的使用.我们知道使用委托可以实现对象行为(方法)的动态绑定,从而提高设计的灵活性 ...
- [.net 面向对象编程基础] (21) 委托
[.net 面向对象编程基础] (20) 委托 上节在讲到LINQ的匿名方法中说到了委托,不过比较简单,没了解清楚没关系,这节中会详细说明委托. 1. 什么是委托? 学习委托,我想说,学会了就感觉简 ...
- 转载 【.NET基础】--委托、事件、线程(2) https://www.cnblogs.com/chengzish/p/4569912.html
[.NET基础]--委托.事件.线程(2) 本文介绍event的使用以及原理,本文接上一篇文章的Demo继续[下载上一篇Demo] 上一篇我们在类(dg_SayHi.cs)里面定义代理了4个Del ...
- 转载 【.NET基础】--委托、事件、线程(1) https://www.cnblogs.com/chengzish/p/4559268.html
[.NET基础]--委托.事件.线程(1) 1,委托 是存放方法的指针的清单,也就是装方法的容器 A, 新建winform项目[01委托],项目中添加dg_SayHi.cs 委托类 用于存储方法 ...
- C#基础系列——委托实现简单设计模式
前言:上一篇介绍了下多线程的相关知识:C#基础系列——多线程的常见用法详解,里面就提到了委托变量.这篇简单介绍下委托的使用.当然啦,园子里面很多介绍委托的文章都会说道:委托和事件的概念就像一道坎,过了 ...
- [C#基础]说说委托+=和-=的那些事
写在前面 为什么会突然想说说委托?原因吗,起于一个同事的想法,昨天下班的路上一直在想这个问题,如果给委托注册多个方法,会不会都执行呢?为了一探究性,就弄了个demo研究下. += 大家都知道委托都继承 ...
- 【.NET基础】--委托、事件、线程(3)
之前的两篇文章我们了解了委托和事件,本文我们看一下线程. 1,一个窗体程序,默认拥有一个线程(相当于一个商店里面,只有一个店员),这个默认的线程叫做 UI线程/主线程. 2,进程和线程的关系: A,进 ...
- 转载 【.NET基础】--委托、事件、线程(3)
之前的两篇文章我们了解了委托和事件,本文我们看一下线程. 1,一个窗体程序,默认拥有一个线程(相当于一个商店里面,只有一个店员),这个默认的线程叫做 UI线程/主线程. 2,进程和线程的关系: A ...
- C#基础篇——委托
前言 在本章中,主要是借机这个C#基础篇的系列整理过去的学习笔记.归纳总结并更加理解透彻. 在.Net开发中,我们经常会遇到并使用过委托,如果能灵活的掌握并加以使用会使你在编程中游刃有余,然后对于很多 ...
随机推荐
- css文字闪烁效果
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- weblogic之CVE-2016-0638反序列化分析
此漏洞是基于CVE-2015-4852漏洞进行黑名单的绕过,CVE-2015-4852补丁主要应用在三个位置上 weblogic.rjvm.InboundMsgAbbrev.class :: Serv ...
- PyDev For Eclipse
eclipse安装Pydev 1.根据自己的eclipse和你安装的python选择可以安装的版本 Update sites for various PyDev versions: Latest ve ...
- 字符型设备驱动程序-first-printf以及点亮LED灯(一)
学习使用 Linux 的 字符型设备驱动 来 进行 . 学习地址:http://edu.51cto.com/lesson/id-25710.html 第一步: 首先写 三个函数 ,2017年5月17 ...
- Java中的集合框架-Collections和Arrays
上一篇<Java中的集合框架-Map>把集合框架中的键值对容器Map中常用的知识记录了一下,本节记录一下集合框架的两个工具类Collections和Arrays 一,Collections ...
- Hive 的collect_set使用详解
Hive 的collect_set使用详解 https://blog.csdn.net/liyantianmin/article/details/48262109 对于非group by字段,可以 ...
- vue 父子组件的生命周期顺序
一.加载渲染过程 父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount ...
- luogu11月月赛T3咕咕咕(组合数学)
题目描述 小 F 是一个能鸽善鹉的同学,他经常把事情拖到最后一天才去做,导致他的某些日子总是非常匆忙. 比如,时间回溯到了 2018 年 11 月 3 日.小 F 望着自己的任务清单: 看 iG 夺冠 ...
- Linux基础-2.目录文件的浏览、管理及维护
1.Linux文件系统的层次结构 1)了解Linux文件系统的树状结构: 在Linux或UNIX操作系统中,所有的文件和目录都被组织成一个以根节点开始的倒置树状结构 2)掌握目录的定义:目录相当于Wi ...
- querySelectorAll 和 getElementBy 方法的区别
作者:简生 链接:https://www.zhihu.com/question/24702250/answer/28695133 来源:知乎 1. W3C 标准 querySelectorAll 属于 ...