前言:

这章我们将弄懂,委托是什么?有什么作用?在什么样的场景下可以启到什么作用?

委托适用的场景:当确定处理一个任务时,不确定其处理任务的方法时可使用,这样可以提高扩展性,调用符合条件的处理方法,避免在程序中大量使用If-Else(Switch)语句。

大家去网上查询委托相关资料都会出现:

委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,

                                             可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。

那么接下来我们一起来解析这段话。

1、委托是个类:

delegate关键字声明委托时,编译器自动为我们生成类。类的名字即为委托变量名,访问类型为定义的委托访问类型。如例中,publice delegate void  TestDelegate(),

那么编译器就会解析为我们生成一个类名为TestDelegate,访问修饰符类型为publice的类,该类继承自[mscorlib]System.MulticastDelegate,任何委托都继承自[mscorlib]System.MulticastDelegate。

2、定义方法类型:

是一种定义方法签名的类型。 当实例化委托时,您可以将其实例与任何具有兼容签名的方法相关联。 相同的方法签名,即参数个数,类型相同,返回值类型相同,所以说委托定义方法的类型。

这里我们定义了一个返回值为空,带一个string类型参数的委托,当我们实例化委托时,开发工具会提示Test委托需要一个无返回值、带一个string类型参数的方法,否则无法实例化。

方法不必与委托签名完全匹配(可以先不管,等我们先弄懂委托后,再去看委托的签名,研究方法与委托的关系):

有关更多信息,请参见 在委托中使用变体(C# 和 Visual Basic)。,引用MSDN中对委托中的协变的解析,当委托方法的返回类型具有的派生程度比委托签名更大时,就称为协变委托方法。因为方法的返回类型比委托签名的返回类型更具体,所以可对其进行隐式转换。这样该方法就可用作委托。协变使得创建可被类和派生类同时使用的委托方法成为可能。请参见http://www.docin.com/p-69978094.html。

3、将方法当作另外一个方法的参数来进行传递:

  class Program
{
static void Main(string[] args)
{
MinisterReturns t = new MinisterReturns();
//实例化一个委托(将签名相同的方法作为参数)
ConsoleApplication2.MinisterReturns.Testdelegate test = new MinisterReturns.Testdelegate(t.Wite);
t.Dele(test, "q1111111");
Console.ReadLine(); }
}
public class MinisterReturns
{
public delegate void Testdelegate(string name);
//签名方法
public void Wite(string name)
{
Console.WriteLine(name);
}
/// <summary>
/// 调用委托函数
/// </summary>
/// <param name="obj">委托函数类型</param>
/// <param name="name">名称</param>
public void Dele(Testdelegate obj, string name)
{
obj(name);//调用委托签名方法进行处理
} }

运行结果:q1111111

4、可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性:

接下来我们可以用一个经典的案例来演示一下,案例情景:不同国家的人说不同的语言。

首先我们先创建一个Speak说话类,里面有个枚举类型,里面包含三个国家,分别是中,英,法,三个说话的方法。

  //说话类
public class Speak
{ //国家
public enum Language
{
China, America, France
}
public void SpeakChinese(string name)
{
Console.WriteLine(name+"在说汉语");
}
public void SpeakEnglish(string name)
{
Console.WriteLine(name+"在说英语");
}
public void SpeakFrench(string name)
{
Console.WriteLine(name+"在说法语");
}
public void SpeakLanguage(string name, Language language)
{
//判断说那种语言
switch (language)
{
case Language.China: SpeakChinese(name); break;
case Language.America: SpeakEnglish(name); break; case Language.France: SpeakFrench(name); break; }
}
} static void Main(string[] args)
{
Speak sp1 = new Speak();
//实例化委托
sp1.SpeakLanguage("aa", Speak.Language.China); sp1.SpeakLanguage("bb", Speak.Language.America);
sp1.SpeakLanguage("cc", Speak.Language.France);
Console.ReadLine(); }

运行结果:

aa在说汉语
                   bb在说英语
                   cc在说法语

现在我们实现了不同国家的人说不同的语言,上面一共有三个国家,如果我还想添加一个国家,需要在Language方法里面添加一个国家,在创建一个说这种语言的方法,还要在switch里面添加一个判断 ,如果添加100种就要判断100次,最后导致代码量多,降低效率。我们这时候就要尝试换个角度去看问题,首先我们需要实现不同国家的人说不同的语言,那么我们的任务就是说话,条件就是不同国家的人说不同的语言,实现说不同的语言就有不同的说话方法(方法不确定)。所以我们可以想到这种场景适合用委托实现。

        首先我们先添加一个委托因为需要分辨不同的人,所以添加一个姓名参数。

public delegate void SpeakLanuageDelegate(string name);

我们将之前的SpeakLanguage方法修改一下。

        /// <param name="name">姓名</param>
/// <param name="languagedelegate">委托类型</param>
public void SpeakLanguage(string name, SpeakLanuageDelegate languagedelegate)
{
languagedelegate(name);
}

接着删除Language枚举,将我们之前的Main方法修改一下,实现将方法当作参数传递给另外一个方法。

       static void Main(string[] args)
        {
      
Speak sp1 = new Speak();
//实例化委托
sp1.SpeakLanguage("aa", new Speak.SpeakLanuageDelegate(sp1.SpeakChinese));
sp1.SpeakLanguage("bb", new Speak.SpeakLanuageDelegate(sp1.SpeakEnglish));
sp1.SpeakLanguage("cc", new Speak.SpeakLanuageDelegate(sp1.SpeakFrench));
Console.ReadLine();
}

运行结果和上次的一样,现在我们可以发现,代码变得更简洁,修改后的代码比之前更具有扩展性。当我们添加新的国家时只需创建一个实现该语言说话的方法,然后实例化一下就行。

-------------------有误之处望指点,共勉。

c#委托之浅析的更多相关文章

  1. C#委托及事件处理机制浅析

    事件可以理解为某个对象所发出的消息,以通知特定动作(行为)的发生或状态的改变.行为的发生可能是来自用户交互,如鼠标点击:也可能源自其它的程序逻辑.在这里,触发事件的对象被称为事件(消息)发出者(sen ...

  2. 浅析C#之委托、Action、Func

    一.委托 1.1 委托的定义 delegate(委托)是一种可用于封装命名方法或匿名方法的引用类型, 委托类似于 C++ 中的函数指针: .Net通过委托来提供回调函数机制. 声明一个委托类型 int ...

  3. 读书笔记 C#委托的BeginInvoke、EndInvoke之浅析

    c#中有一种类型叫委托,它是一种引用类型.可以引用静态与非静态的方法,且这些方法的参数列表和返回值类型必须与所声明的委托一致. 委托引用的方法可以通过BeginInvoke和EndInvoke来异步进 ...

  4. c#进阶之浅析委托和事件

    何为委托 加了delegate关键字,没有方法体{}的方法模版(方法列表);委托是一种类型 public void Write() { //TODO } //加上关键字delegate,去掉方法体{} ...

  5. C# 委托浅析

    C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针.委托(Delegate) 是存有对某个方法的引用的一种引用类型变量.引用可在运行时被改变. 委托(Delegate)特别用于实现 ...

  6. C#回调浅析(委托、接口回调)

    https://wenku.baidu.com/view/ed724173bd64783e08122b2f.html

  7. 【深入浅出jQuery】源码浅析2--奇技淫巧

    最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...

  8. Reactive Extensions(Rx)并发浅析

    Reactive Extensions(Rx)并发浅析 iSun Design & Code .Net并行编程 - Reactive Extensions(Rx)并发浅析 关于Reactive ...

  9. C# Winform窗口之间传值的多种方法浅析(转)

    摘要http://www.jb51.net/article/63837.htm 这篇文章主要介绍了C# Winform窗口之间传值的多种方法浅析,本文起讲解了通过构造器传值.通过属性传递.通过事件携带 ...

随机推荐

  1. docker学习笔记(2)

    docker镜像及容器常用命令 一.docker镜像 docker pull # docker pull nginx Using default tag: latest latest: Pulling ...

  2. npm run dev的错误

    一直出现这个问题,有试过重新npm安装之类的,也试过替换文件,后来才知道原来是我在初始目录下执行run,应该cd到该项目下在run,如图 firsttest是我的项目名字

  3. loadrunner11浏览器兼容性的问题

    最近项目中遇到了新开发的系统,全是HTML5和一些最新的前端框架技术,由于没有做浏览器兼容处理,所以该系统无法在IE浏览器进行操作,对firefox和google浏览器支持较好.但是又一个问题出现了, ...

  4. 《Machine Learning Yearing》读书笔记

    ——深度学习的建模.调参思路整合. 写在前面 最近偶尔从师兄那里获取到了吴恩达教授的新书<Machine Learning Yearing>(手稿),该书主要分享了神经网络建模.训练.调节 ...

  5. 配置DTP

    拓扑一  结果:NO 默认auto(被动)模式 Switch>show interfaces fastEthernet / switchPort Name: Fa0/ Switchport: E ...

  6. 使用XHProf查找PHP性能瓶颈

    XHProf是facebook 开发的一个测试php性能的扩展,本文记录了在PHP应用中使用XHProf对PHP进行性能优化,查找性能瓶颈的方法. 一.安装Xhprof扩展 //github上下载ht ...

  7. TCP/UDP 网络工具

    1. 统计连接状态 netstat -n | awk '/^tcp/ {++State[$NF]} END {for(s in State) print s, State[s]}' CLOSE_WAI ...

  8. 数学paper写作注意事项

    [转载请注明出处]http://www.cnblogs.com/mashiqi 2019/03/20 Introduction一定要好好写,写好后要至少读一遍,保证流畅.editor会读introdu ...

  9. react抛物线小球实现

    .ballFather{ position: absolute; width: 15px; height: 15px; border-radius: 50%; transition: all 0.5s ...

  10. 约瑟夫斯问题-java版数组解法和链表解法

    10个人围成一圈,从1到10编号,从1开始数,数到3或3的倍数的位置,则该位置的人出局,求最后剩下哪一个号? 数组解法: 数组存放数组:a[10]存在1到10编号人 数组遍历到尾部又从头遍历:遍历数组 ...