一聚教程网:一个值得你收藏的教程网站

热门教程

asp.net C# 委托的使用学习笔记

时间:2022-06-25 08:16:36 编辑:袖梨 来源:一聚教程网

委托一词源于生活,在生活中我们经常做或看见一些被委托或委托别人的事。比如:


 

场景1:“由于刘翔还在美国疗伤,特委托我带他领取今天的奖项,……”

场景2:“由于小明的爸爸妈妈忙,特委托我来参见今天的家长会,……”

场景3:“刘师傅,我这里是在是走不开,下班后麻烦你帮我接下孩子,谢谢……”

…………


 

以上诸多情况都是生活中委托的形式,总之,委托可以理解为我请(委托)别人做事,或别人请(委托)我做事。


 

现在我们将上面的故事再发展一下。现在社会越来越讲究高效、专业,各种各样的服务公司随处可见,而社会的压力和忙碌的工作造就了许许多多的剩男剩女,“婚姻介绍所”遍地开花。“找对象”成了不得不面对的棘手的问题。现在我们就以“小胡”找对象为案例,分析一下“委托”到底有什么特点。


 

我们从以下几个方面分析小胡找对象的事件:


 

1.最终目标:小胡需要通过“找对象”找到一个“对象”

2.找对象的方式:

   1. 自己找

   2. 通过“鹊桥”婚姻介绍所找

   3. 通过别的途径找,托人、“非诚勿扰”、“我们约会吧”等等(但这其实也是“”介绍所。模式,只是看似更高级一些)。


 

如果我们用OO的思想去分析上面的事件不难总结出这么些对象或类,以及关键功能。


类:“剩男剩女”,小胡是其中的一个对象

类:“婚姻介绍所”,鹊桥婚姻介绍所是其中一个对象

功能:找对象


 

接下来分析两种不同找对象方式(法)的不同。


 

1)自己找

相当于“剩男剩女”们自己具备了“找对象”功能,一切过程有自己控制。这个时候这个参与者只有“小胡”一个对象


 

2)通过婚姻介绍所找

这种情况下,小胡自己不具备自己找对象的功能了,而是请(委托)具有“找对象”的介绍所帮忙找对象,这样看似参与者有两个,分别是“小胡”和“鹊桥”。但其实(我认为),婚介所只是一个代理结构,这个机构本身是不具备帮人“找对象”的功能的,它之所以可以帮人找对象,是因为婚介所有大量的工作人员——专业媒婆,所以最终负责找对象的是“媒婆”,经过这么一分析,通过婚介所找对象的参与者就有三个,分别是“小胡”,“鹊桥”和众多“媒婆”。


 

从功能的供给关系看,两种找对象的方式有着本质的区别。


 

“自己找”相当于供给双方均为自己;通过“婚介所”找,功能的提供者是“媒婆”,功能的使用者是“小胡”,而“婚介所”则负责管理“小胡”和“媒婆”之间的关系。


 

分析到这里,似乎出现了漏洞,有朋友肯定想,“我既不通过自己找,也不通过婚介所找,我直接通过媒婆找”,诶,确实是个不错的主意,马上来分析一下。在这种情况下,参与者只有两个,“小胡”和“XX媒婆”。


 

综上所述,找对象有三种方式:

1.自己找

2.自己找媒婆找

3.自己找婚介所(婚介所通过媒婆)找


 

一共可能出现的参与者有三个:小胡、婚介所、和XX媒婆


 

下图表示了三种找对象方式的关系图。


C 委托的使用 - 胡杰 - 胡杰的博客
 

 

现在我们抛开第一种情况,来讨论一下后面两种情况的区别。


 

从上图可以看出,功能的需求者是“小胡”,功能的提供者是“XX媒婆”,在第二种情况下,功能的需求者和功能的提供者直接发生了关系,功能需求者必须知道有什么样的功能提供者;而在第三种情况下,功能的需求者和功能的提供者被“婚介所”隔开,功能的需求者彻底和功能的提供者分开了,即“小胡”(功能需求者)不知道是哪个媒婆(功能提供者)为他找对象(提供服务),“媒婆”也可以不知道“小胡”到底是谁(为谁服务),这样婚介所就起到隔离和联系功能需求者和功能提供者的作用。


 

更重要的是,在第二种情况下,功能的提供者必须先存在,即必须先有媒婆,小胡才能和媒婆取得联系;而在第三种情况下,功能的提供者不必先存在,即可以先由小胡向婚介所提出功能需求,婚介所再招募(或将其他人变成)媒婆来找对象。这样,两种情况就发生了根本性的区别:第二种情况功能需求者只能调用已经存在的功能的提供者的功能,第三种情况下,功能需求者可以通过中介(委托机构)调用未来(未知)的功能提供者的功能(神奇吧!)。


 

接下来让我们通过一组问答来分析下“婚介所”和“媒婆”(功能提供者)的关系。


 

问:媒婆可以有除帮人“找对象”以外的功能吗?

答:那是必须的,俺们还能送大桶水呢。

问:一次只能派一个媒婆帮人找对象吗?

答:非也,只要有money,可以全体出动。

问:难道只能通过专业媒婆来找对象吗?

答:非也,只要有money,可以发动一切亲朋好友,全场出动。


 

从上面的场景我们看得到以下信息:


1. 功能提供者可以提供多种功能,但“婚介所”只需要“找对象”功能即可。

2. 只要是和“婚介所”关联的媒婆都可以出动(找对象)

3. “婚介所”不止可以通过专业媒婆找对象,还可以通过一切有关联的具有“找对象”功能的人来找对象。


 

OK,就分析这么多,是时候总结一下委托是什么啦。


 

委托就是一个可以管理和调用提供某个功能的对象的中介机构,功能使用者通过委托来间接调用功能提供的功能。


二、基本委托


正如上面所述,“委托可以管理和调用某个功能”,功能在C#中的表现形式为方法,而定义方法的关键是“返回类型”和“参数”,方法的调用者正是通过这两个关键信息来使用方法。所以委托就是一个方法的定义原型。但委托本身和class一样属于引用类型。


 

定义语法


 

访问修饰符 delegate 返回类型 委托名(参数列表)


 

如:


public delegate string XxxHandler(string str,int i);

public delegate void ClickHandler(object sender,EventArgs);


 

定义委托对象


 

XxxHandler handler = new XxxHandler(Xxx.静态方法名);

XxxHandler handler = new XxxHandler(xxx对象.实例方法名);


 

定义委托时关联的方法的签名必须委托的签名一致,否则不能关联


 

调用委托


 

handler(参数值,……)


 

以下是“找对象”C#版本的实现


 

///


/// 表示被找的对象类型
///

public class 对象{ }

///
/// 委托:相对于婚介所
///

///
///
public delegate 对象 找对象代理(String 要找的对象的要求);

///
/// 功能的需求者
///

public class 剩男剩女 {
public 剩男剩女(String name) {
this.Name = name;
}
public String Name { get; set; }

public void 直接通过媒婆找对象(媒婆 媒婆,String 要求) {
媒婆.找对象(要求);//将要求直接告诉媒婆,必须知道媒婆的存在
Console.WriteLine(this.Name+"成功的通过媒婆找到了对象,从此过上了幸福的生活……");
}

public void 通过婚介所找对象(找对象代理 婚介所, String 要求) {
if (婚介所!=null) {
婚介所(要求);//调用委托,将要求直接告诉婚介所,不需要知道具体的媒婆
}
Console.WriteLine(this.Name + "成功的通过婚介所找到了对象,从此过上了幸福的生活……");
}
}

///
/// 功能的提供者
///

public class 媒婆 {
public 媒婆(String name) {
this.Name = name;
}
///
/// 姓名
///

public String Name { get; set; }

public 对象 找对象(String 要求) {
Console.WriteLine("媒婆"{0}"正在找"{1}"的对象",Name,要求);

return new 对象();
}
}

class Program {
static void Main(string[] args) {
//定义一个媒婆对象
媒婆 媒婆张 = new 媒婆("媒婆张");
//定义小胡对象
剩男剩女 小胡 = new 剩男剩女("小胡");

//***直接调用媒婆的方法找对象
小胡.直接通过媒婆找对象(媒婆张, "圆圆的脸蛋、圆圆的眼睛");

//***通过委托来找对象
//定义委托
找对象代理 婚介所 = new 找对象代理(媒婆张.找对象);
小胡.通过婚介所找对象(婚介所, "圆圆的脸蛋、圆圆的眼睛");

Console.ReadKey();
}
}

 

 

C 委托的使用 - 胡杰 - 胡杰的博客

 

 

以上代码我们首先重点关注的“剩男剩女”类中两个找对象方法的不同的定义和使用方法。在“直接通过媒婆找对象”方法中,参数中包含了“媒婆”对象,那么从定义类的先后顺序来看,我们必须先写好“媒婆”类,才能写好“剩男剩女”类,或者说“剩男剩女”类依赖于“媒婆”类;在“通过婚介所找对象”方法中,参数中的媒婆类变成了“找对象代理”类型的对象,这样在该方法(或“剩男剩女”类)中就不会出现“媒婆”了,或者说“剩男剩女”类不依赖于“媒婆”类啦,那我们在写“剩男剩女”类时可以不必知道“媒婆”类的存在(看出区别来了吧?)。


 

Program 类测试方法中,两个方法的调用形式也不同。调用直接通过媒婆找对象”的方法之前必须定义媒婆对象;调用“通过婚介所找对象”方法之前必须定义媒婆对象和委托对象。诶,慢点,“通过委托调用方法比直接调用复杂些”。是的,调用时确实复杂些,但这不是委托的重点,重点是,通过委托,我们拆散了“剩男剩女”和“媒婆”类的依赖,解放了“剩男剩女”类,而通过测试类中定义和传递的委托,我们依然可以调用“媒婆”的方法,甚至可以调用任何类的符合委托签名的方法(这就是最神奇的地方!)。


三、多播委托


在上面的代码中,我们看到通过委托确实可以间接在“剩男剩女”类中调用“媒婆”的找对象的方法。但在上面的代码中婚介所(委托)只雇佣了一个媒婆(媒婆张)来找对象,那么,能雇佣多个媒婆一起找对象吗?当然可以,请看以下测试类代码。


class Program {
static void Main(string[] args) {
//定义多个媒婆对象
媒婆 媒婆张 = new 媒婆("媒婆张");
媒婆 媒婆李 = new 媒婆("媒婆李");
媒婆 媒婆黄 = new 媒婆("媒婆黄");
//定义小胡对象
剩男剩女 小胡 = new 剩男剩女("小胡");
//定义委托并关联多个媒婆
找对象代理 婚介所 = new 找对象代理(媒婆张.找对象);
婚介所 += new 找对象代理(媒婆李.找对象);
婚介所 += new 找对象代理(媒婆黄.找对象);
小胡.通过婚介所找对象(婚介所, "圆圆的脸蛋、圆圆的眼睛");
Console.ReadKey();
}
}

 


 

 

C 委托的使用 - 胡杰 - 胡杰的博客

 

 

从输出的效果图中可以看出,婚介所同时调用了三个媒婆的找对象的方法,这种效果是“直接通过媒婆找对象”无法办到的。那么,该委托只能调用“媒婆”的找对象的方法吗?当然不是。


 

我们在程序中加入“朋友”类,添加一个“介绍”的方法。代码如下:


public class 朋友 {
public 对象 介绍(String 要求) {
Console.WriteLine("朋友介绍了一个 "{0}" 的对象", 要求);
return new 对象();
}
}

 

 

调整后的测试类

class Program {
static void Main(string[] args) {
//定义一个媒婆对象和朋友对象
媒婆 媒婆张 = new 媒婆("媒婆张");
朋友 小王 = new 朋友();
//定义小胡对象
剩男剩女 小胡 = new 剩男剩女("小胡");
//定义委托并关联多个媒婆
找对象代理 婚介所 = new 找对象代理(媒婆张.找对象);
婚介所 += new 找对象代理(小王.介绍);
小胡.通过婚介所找对象(婚介所, "圆圆的脸蛋、圆圆的眼睛");
Console.ReadKey();
}
}

 

C 委托的使用 - 胡杰 - 胡杰的博客

 

 

从输出的效果图中可以看出,委托成功的调用了关联的“媒婆张”和朋友“小王”的方法。我们把这种调用一次委托可以调用多个方法的委托就称为“多播委托”,即一次命令多人执行。


四、匿名委托


委托的功能是强大的,但对于初学者来说也是个难以突破的难点,但只要按照一定的步骤其实也没有想象中的那么难。


 

使用委托的步骤

1. 定义委托

2. 定义使用委托的类

3. 在类中像调用方法一样调用委托

4. 定义某些类,其中包含签名与委托一样的方法

5. 在测试类中定义具体的委托对象并与某些方法关联

6. 调用使用了委托的方法


 

从上面的代码和总结的步骤可以看出,要调用委托必须“定义某些类,其中包含签名与委托一样的方法”,这样才能让委托能和这些方法关联。


 

匿名委托就是一种无需在专门的类中定义方法再与委托关联的形式的委托,即使用匿名委托无需再定义专门的类和方法了,比如案例中的“媒婆”类和“朋友”类。使用起来更快捷、简单。


 

使用匿名委托改造测试类


class Program {
static void Main(string[] args) {
剩男剩女 小胡 = new 剩男剩女("小胡");
//第一种形式
找对象代理 婚介所=delegate(string 要求){
Console.WriteLine("不需要媒婆也能找到"{0}"的对象", 要求);
return new 对象();
};
小胡.通过婚介所找对象(婚介所, "圆圆的脸蛋、圆圆的眼睛");
//第二种形式
小胡.通过婚介所找对象(delegate(string 要求) {
Console.WriteLine("不需要媒婆也能找到"{0}"的对象", 要求);
return new 对象();
}, "圆圆的脸蛋、圆圆的眼睛");
Console.ReadKey();
}
}


 

C 委托的使用 - 胡杰 - 胡杰的博客

 

 

使用第一种形式定义委托,代码中没有了媒婆类和朋友类,而是直接通过delegate关键字直接声明了一个签名与“找对象代理”委托签名一样的方法,这样调用该委托就会调用该方法。但这种形式中委托对象依然有名字(婚介所)。


 

在第二种形式中,方法的参数位置直接通过delegate关键字定义了一个与委托签名一样的方法,委托没有了名字,真正“匿名”啦,而且用第二种形式调用,原本的委托类型“找对象代理”也没有用到,我们唯一需要知道的就是委托的方法签名,委托到底是什么名字就可以忽略啦。


五、内置委托Func


如果使用匿名委托,那么我们使用委托的步骤就变了。


 

使用委托的步骤

1. 定义委托

2. 定义使用委托的类

3. 在类中像调用方法一样调用委托

4. 测试类调用方法时直接使