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

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. 关于UITableView 不能回调 tableView: cellForRowAtIndexPath的问题

    做项目时始终遇到一个问题,tableview不能回调cellForRowAtIndexPath方法,导致cell不能显示. 在网上没找到合理的解决方案. 自己弄了一下,按照自己的推测解决了这个问题 首 ...

  2. Echarts 嵌套饼图实现,内环点击控制外环显示

    Echarts有交互事件,但是如果用其进行图形变更,恐怕就只有重新修改配置了. 如图,我想要实现,内圈的数据控制外圈的图形,当点击内环的某一块时,就可以实现,更改外环的目的. 起初我想能不能直接修改o ...

  3. 4、Python文件操作工具 xlsxwriter 工具

    # _*_ encoding:utf-8 _*_ import xlsxwriter #创建xlsx后缀名的excelexcel = xlsxwriter.Workbook(r'D:\github\f ...

  4. programming-languages学习笔记--第3部分

    programming-languages学习笔记–第3部分 */--> pre.src {background-color: #292b2e; color: #b2b2b2;} pre.src ...

  5. 说说Vue.js的v-for

    v-for的话,相比传统的jQuery的  $.each或者for循环要简洁明了的多, 比如在Jquery中我要遍历数据,通常如下几种方式: $.each(apps, function(i, app) ...

  6. [转]DbHelper通用数据库访问帮助类

    之前我一直都是在博客园中查看各位高手的博文,确实学到了不少知识,不过比较少写博客,现在就把我自己在项目实施过程中使用到比较好的技术框架写出来,希望能让更多的人了解和学习. 通常我们在开发使用数据库访问 ...

  7. ASP.Net GridView 基础 绑定字段

    通过以前的学习,我们实现了效果如下: 现在我想修改显示/隐藏部分列,有两种做法: 一.在配置数据源的时候不是有查询哪些字段的吗,去除不需要的字段,重新绑定. 二.就是直接编辑列 下面是分析每种字段类型 ...

  8. MFC文档应用程序CToolBar:设置两个工具条并列停靠到同一条边上 转

    转自:http://blog.csdn.net/panshiqu/article/details/9369891# 将多个工具条同时并列停靠在某窗口的某一条边上.对于这种停靠方法,利用上述工具条控制函 ...

  9. Linux-- 查看文件 more与其它

    more 翻页查看 用法:more 文件名 nl 显示行号打印(不常用) 1.不打印空白行行号:nl -b t 文件名 类似 cat -b 文件名 2.打印所有行行号:nl -b a 文件名 类似 c ...

  10. 有关dubbo面试的那些事儿

    dubbo是什么 dubbo是一个分布式框架,远程服务调用的分布式框架,其核心部分包含: 集群容错:提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集 ...