为什么用委托

Posted zjone391

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么用委托相关的知识,希望对你有一定的参考价值。

 刚学习委托时无论老师怎么开导,我都是一头雾水,不是听不懂,也不是不会写,就是不明白为什么要用委托,看不出来一点好处,而且写很多没用的代码,每当这么问老师时,老师总说:用委托会使你的代码更灵活,我的天啊,和没说一样,后来参加工作了两年竟然一直没有用到委托也没什么觉得不妥,直到有一天看到了张子阳的“事件和委托”让我大吃一惊研读了几天终于弄懂了一点事件和委托,这时突然感觉以前写的程序都不是程序,起码不是面向对象的程序,因为事件和委托是面向对象编程精髓。

     上几天一个同事问我什么是委托,我告诉他:“委托是方法的指针,可以把方法当参数用......,懂么?”,他说懂了。他又问我为啥要用委托不用不行么我依然可以实现委托能实现的任何功能,这时我想像我老师一样的告诉他,他肯定会和我一样迷糊2年,于是我给他出了一道题:实现一个能定时做某事的类就像winform的timer一样的东西,他实现的代码如下:

 public class Timer
{
public static void start(int sleep)
{
  ThreadStart ts = new ThreadStart(DoSomething);
  Thread th = new Thread(ts);
  th.Start();
}
/// <summary>循环做事
/// </summary>
public static void DoSomething()
{
  while (true)
  {
  writeFile();
  Thread.Sleep(1000);//线程休眠1秒
}
}
/// <summary>写文件
/// </summary>
public static void writeFile()
{
  System.IO.StreamWriter sw = new System.IO.StreamWriter("path");
  sw.Write("ok");
  sw.Close();
  sw.Dispose();
}
}

 

恩,很快就实现了,可以1秒钟写一次文件,那我要一秒钟向数据库插入一条记录呢?于是他修改代码如下:

public class Timer

{
   public static int doType = 0;
   public static void start(int sleep)
   {
    ThreadStart ts = new ThreadStart(DoSomething);
    Thread th = new Thread(ts);
    h.Start();
   }
        /// <summary>循环做事
        /// </summary>
        public static void DoSomething()
        {
            while (true)
            {
                if (doType == 0)
                    writeFile();
                else if(doType==1)
                    InsertDB();
                Thread.Sleep(1000);//线程休眠1秒
            }
        }
        /// <summary>写文件
        /// </summary>
        public static void writeFile()
        {
            System.IO.StreamWriter sw = new System.IO.StreamWriter("path");
            sw.Write("ok");
            sw.Close();
            sw.Dispose();
        }
        public static void InsertDB()
        {
            //写数据库
        }
 
}
 
这不是很容易么?你要做啥事都行,我只要加分支判断就可以了。我问他:先不说你这些代码是否符合“开闭原则”和"单一职责原则",就说你这代码别人要怎么使用,拷过去添加一个方法再添加一个分支判断?你起码提取一下做个通用类,像winform的timer一样别人只要传给你两个参数1.间隔时间,2.要做的事,剩下就是你的事了。于是他又修改了代码:
public class Timer
{
    public static void start(int sleep, ? doSomething)
    {
 
    }
}
他写到这说:不会写了,我不知道doSomething应该是啥类型,他是别人传给我要执行的方法。我告诉他doSomething的类型就应该是一个委托,委托适合用在某时或某种情况执行某些事,而这些事你事先并不知道是啥。就像本例中,你想间隔1秒钟替别人执行某件事,但你设计这个类的这个方法时还不知道别人到底要你做什么事。用现实生活中的示例做比喻:一个律师能替人打官司,他可以打任何类型的官司,但只有原告委托律师打官司时律师才知道自己要打什么类型的官司,所以律师就是一个委托。好了下面我们来看一下我实现的Timer类:
 
 
public class Timer
{
  public delegate void TimerHandler();
  public static void start(int sleep, TimerHandler doSomething)
  {
    ThreadStart ts = new ThreadStart(() => { while (true) { Thread.Sleep(sleep); doSomething(); } });
    Thread th = new Thread(ts);
    th.Start();
  }
}
由于当时我正在学习匿名方法和Lambda所以ThreadStart参数用Lambda代替了具体的函数。
 
 
委托可以理解为:将一些有相同特征的函数(参数个数,参数类型)抽象成一个公用的委托,委托其实可以认为是这些相同特征函数的一个别名。
1、调用这些函数组中的某一个函数时,只要实例化出这样的一个委托对象,通过这个委托对象传入相应的参数即可实现调用原函数的目的。
2、多路广播委托,委托对象的绑定

static void Main(string[] args)
{

GetTest test = new GetTest(A);
test += new GetTest(B);
test();

Console.Read();
}

public delegate int GetTest();

public static int A()
{
Console.WriteLine("A");
return 1;
}
public static int B()
{
Console.WriteLine("B");
return 1;
}

 
 
 
 

 

以上是关于为什么用委托的主要内容,如果未能解决你的问题,请参考以下文章

关于C#委托 有个显示样式的功能,用委托怎么做

原生js如何绑定a连接点击事件?

C#系列:其实委托很简单(下)

c#中委托怎么用

iOS UIPopoverController委托不工作,仍然是零

对于委托,我这小菜鸟的理解。