VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > temp > C#教程 >
  • c#初学课程写给初学者委托的概念

制作者:剑锋冷月 单位:无忧统计网,www.51stat.net
 

  有时我们需要将一个函数作为另一个函数的参数,这时就要用到委托(Delegate)机制。委托是一个较难讲清楚的概念,笔者苦思数日,终于想出了一个巧妙的例子。

  下面我们设计一个马戏表演函数RunCircus(),它的第一个参数是代表动物的函数,传给它什么样的动物,就进行什么动物的表演。请新建一个名为“Delegate”的项目,然后添加如下代码。

  试一试:定义委托    //《C#初学课堂》  

  //函数:狗表演    static void DogAct(string name)
    {
      Console.WriteLine("Hello,I am " + name + "!");
      Console.WriteLine(@"
          .----.
         _.'__  `.
       .--(#)(##)---/#
      .' @     /###
      :     ,  #####
      `-..__.-' _.-###/
         `;_:  `''
        .'''''''`.
        /,Snoopy ,
       // COOL! 
       `-._______.-'
       ___`. | .'___
       (______|______)");
    }
     //函数:猫表演    static void CatAct(string name)
    {
      Console.WriteLine("Hello,I am " + name + "!");
      Console.WriteLine(@"
       .-. __ _ .-.
        | ` /  |
        /   '.()--
       |    '._/
       _| O  _  O |_
       =  '-'  /=
        '-._____.-'
        /`/___/`
       //o   o/
       (_|     |_)
        |____,____|
        (____|____)");
    }
     //函数:狮子表演    static void LionAct(string name)
    {
      Console.WriteLine("Hello,I am " + name + "!");
      Console.WriteLine(@"
           ,%%%%%%%%,
           ,%%/%%%%/%%
          ,%%%c "" J/%%%
     %.    %%%%/ o o %%%
     `%%.   %%%%  _ |%%%
      `%%   `%%%%(__Y__)%%'
      //    ;%%%%`-/%%%'
      ((    / `%%%%%%%'
        .'     |
        /     | |
       /    ) | |
             /_ | |__
        (___________)))))))");
    }
    //定义委托
    delegate void AnimalAct(string name);
    //函数:马戏表演(第一个参数为AnimalAct型委托)
    static void RunCircus(AnimalAct animalAct, string name)
    {
      animalAct(name);
    }
    static void
Main
(string[] args)
    {
      //把函数DogAct()转换为AnimalAct型委托
      AnimalAct deleDogAct = new AnimalAct(DogAct);
      //把委托deleDogAct传给函数RunCircus()
      RunCircus(deleDogAct, "Snoopy");
      //把函数CatAct()转换为AnimalAct型委托,并传给函数RunCircus()
      RunCircus(new AnimalAct(CatAct), " Kitty ");
    }

 

  运行结果如下:

  [C#初学课堂]写给初学者:委托的概念

  《C#初学课堂》

  函数RunCircus(AnimalAct animalAct, string name)的第一个参数实际上是一个代表动物的函数,传给它什么样的函数,它就用什么样的动物进行表演。但为了进行严格的类型检查,我们不能直接把函数的名称传递给它,而应先定义一个委托(Dlelegate),即定义一种“函数类型”。

  [C#初学课堂]写给初学者:委托的概念

  委托用关键字delegate声明,上面的语句定义了一种名为AnimalAct的委托(函数类型),明确规定了委托的参数类型和返回值类型。当我们需要把某个函数作为参数时,就要先把它转换为委托实例。

  [C#初学课堂]写给初学者:委托的概念

  然后把这个委托实例以参数的形式传递给调用它的函数。

  [C#初学课堂]写给初学者:委托的概念

  由此可以看出委托实例deleDogAct实际上是函数DogAct()的别名,显然委托和被委托函数应具有相同的参数类型和返回类型。

  在我们的程序中,马戏团总是调用函数RunCircus()进行表演。定义函数RunCircus()时,我们不知道也不关心传递给它的委托代表哪个函数,直到调用RunCircus()函数,并把实际参数传递给它时,这个函数才具体化。传给它什么样的实际参数,就进行什么样的表演,传给它deleDogAct委托,马戏团就进行狗的表演;传给它deleCatAct委托,马戏团就进行猫的表演;传给它deleLionAct委托,马戏团就进行狮子表演。因此以委托为参数的函数具有一定的通用性。

 

  下面我们利用委托的通用性设计一个通用的求定积分的函数。

  [C#初学课堂]写给初学者:委托的概念

  数得形式传递给定积分函数,所以需要利用委托实现。

  请新建一个名为“Integral”的项目,然后添加如下代码。

  试一试:求定积分

   //《C#初学课堂》
   //被积函数
    {
      return 2*x+1;
    }
    //被积函数
    {
      return x * x ;
    }
   //被积函数的委托
    delegate double Integrand(double x);
    //函数:定积分
    static double DefiniteIntegrate(double a, double b, Integrand f)
    {
      const int sect = 1000;    //分割数目
      double delta = (b - a) / sect;
      double area = 0;
      for (int i = 1; i <= 1000; i++)
      {
        area += delta * f(a + i * delta);
      }
      return area;
    }
    //进行定积分运算
    static void
Main
(string[] args)
    {
      Integrand f1 = new Integrand(F1);
      Integrand f2 = new Integrand(F2);
      double result1 = DefiniteIntegrate(1, 5, f1);
      double result2 = DefiniteIntegrate(0, 1, f2);
      Console.WriteLine("result1 = {0}", result1);      Console.WriteLine("result2 = {0}", result2);
    }
  

[C#初学课堂]写给初学者:委托的概念

 

   只需传给定积分函数DefiniteIntegrate()相应的被积函数,就可计算出任何函数的定积分。

   综上所述,利用委托可以实现以函数为参数,提高程序的通用性。委托用关键字的delegate声明,实际上创建一种委托相当于创建一个从System.Delegate派生出来的类,类中有一个调用列表,列表中包含着被委托函数的引用。与C++的函数指针相比,委托是一种类型安全的方式。《C#初学课堂》

  static double F1(double x)

  static double F2(double x)

 

 

  运行结果如下:

  [C#初学课堂]写给初学者:委托的概念

  《C#初学课堂》

  函数RunCircus(AnimalAct animalAct, string name)的第一个参数实际上是一个代表动物的函数,传给它什么样的函数,它就用什么样的动物进行表演。但为了进行严格的类型检查,我们不能直接把函数的名称传递给它,而应先定义一个委托(Dlelegate),即定义一种“函数类型”。

  [C#初学课堂]写给初学者:委托的概念

  委托用关键字delegate声明,上面的语句定义了一种名为AnimalAct的委托(函数类型),明确规定了委托的参数类型和返回值类型。当我们需要把某个函数作为参数时,就要先把它转换为委托实例。

  [C#初学课堂]写给初学者:委托的概念

  然后把这个委托实例以参数的形式传递给调用它的函数。

  [C#初学课堂]写给初学者:委托的概念

  由此可以看出委托实例deleDogAct实际上是函数DogAct()的别名,显然委托和被委托函数应具有相同的参数类型和返回类型。

  在我们的程序中,马戏团总是调用函数RunCircus()进行表演。定义函数RunCircus()时,我们不知道也不关心传递给它的委托代表哪个函数,直到调用RunCircus()函数,并把实际参数传递给它时,这个函数才具体化。传给它什么样的实际参数,就进行什么样的表演,传给它deleDogAct委托,马戏团就进行狗的表演;传给它deleCatAct委托,马戏团就进行猫的表演;传给它deleLionAct委托,马戏团就进行狮子表演。因此以委托为参数的函数具有一定的通用性。



相关教程