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开发中,我们经常会遇到并使用过委托,如果能灵活的掌握并加以使用会使你在编程中游刃有余,然后对于很多 ...
随机推荐
- Asp.net & Aspose.cells 导出
protected void btnExport_Click(object sender, EventArgs e) { DataTable tbBooks = (DataTable)Session[ ...
- Html5 移动应用软件开发框架 JqueryMobile SenchaTouch 介绍
一.JqueryMobile 介绍 jQuery Mobile 是 jQuery 在手机上和平板设备上的版本. jQuery Mobile 不仅会给主流移动平台带来 jQuery 核心库,而且会发布一 ...
- Mac Sublime Text3快捷键
下载地址http://www.sublimetext.com/3 一.安装Package Control 按Ctrl + ` 调出console,粘贴下列安装代码到底部命令行并回车: import u ...
- css注入获取网页中的数据
<style><?php echo htmlspecialchars($_GET['x']);?></style> <br><br>< ...
- 基于Azure Blob冷存储的数据压缩算法测试对比分析
背景说明: 近期公司的数据增量迅速增长,存储的成本太高,需要采用生命周期进行管理,热存储中的数据或者被删除,或者备份至冷存储.但是冷备时是否要压缩,需要进行验证.Azure本身没有提供压缩的接口,只能 ...
- ASP.NET MVC & WebApi 中实现Cors来让Ajax可以跨域访问 (转载)
什么是Cors? CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing).它允许浏览器向跨源服务器,发出XMLHttpReq ...
- 精准测试白皮书v3.0-2019最新版
现代社会是建立在各种以计算机为基石的软件技术基础之上的.随着日新月异的需求变化,软件系统越来越复杂.很多人觉得软件开发才是重要环节,但实际上,无法对大型软件进行有效的质量把控,就无法真正构建与维护大型 ...
- C#多个if与if+多个else if有何不同?
int a=1; if(a==1){System.out.println("1");} if(a==2){System.out.println("2");} i ...
- java.lang.IllegalStateException: Failed to load property source from location 'classpath:/application.yml'
java.lang.IllegalStateException: Failed to load property source from location 'classpath:/applicatio ...
- JDK1.8降到1.7技巧
前言: 最近部署一个产品,该产品不支持JDK1.8,碰巧我的机器安装的是1.8,这就需要降到1.7才能部署启动成功.那么我也是不赞成卸载1.8来安装1.7,因为很多时候可能需要1.8和1.7来回切换. ...