《C#入门详解》刘铁猛 delegate

delegate

  • 什么是委托

 

《C#入门详解》刘铁猛      delegate

例子:

namespace delegateExample
{
  class program
   {
    static void main(string[] args)
    {

     Calculator calculctor = new Calculator();
     Action action = new Action(calculator.report); //只需要方法名,new Action(calculator.report()) 加括号代表调用这个方法
/*========这边定义了一个指针变量,把方法名赋给指针变量========读取函数指针存储的值获得函数所在地址=======又因为这个指针变量是委托,委托是一个类,所以这个指针变量以声明一个类来定义*/
     calculator.report();   //直接调用
     action.invoke();       //间接调用
     action();                 //简略写法
     }
    }

  class Calculator
  {
   public void report(){console.writeline("i have method");}
   public int add(int a,int b){int result=a+b;return result;}
   }

}
  • 自定义委托

《C#入门详解》刘铁猛      delegate

namespace delegateExample
{
 public delegate double Calc(double x,double y);
 class program
  {
    static void main(string[] args)
    {
     Calculator calculator = new Calculator();
     Calc calc = new Calc(calculator.add);
     double a =100;
     double b=200;
     double c=0;
     c = calc.invoke(a,b);
     c = calc(a,b);
     console.writeline(c);
     }
   }

   class Calculator
   {
     public double add( double x, double y){ return x+y;}
    }

}
  • 委托的一般使用

《C#入门详解》刘铁猛      delegate

          1.委托的一般使用:把委托当作方法的参数传递到方法中去。Advantage:写了一个方法,这个方法有一个委托类型的参数,委托封装了一个方法。在方法体中使用传进来的这个委托间接调用委托封装了的方法,这样就形成了一种动态调用方法的代码结构

          2.模板方法:写了一个方法,通过传进来的委托参数,“借用”指定的外部方法来产生结果。这就相当于在我写的方法中有一个“填空题”,“填空题”的空白之处就用传进来的委托类型的参数进行填补。也就是通过传进来的委托类型的参数间接的调用我指定的外部方法,这个方法一般有返回值。当我拿到这个返回值在继续执行我所写方法后面的逻辑。

          3.回调方法:某个方法我可以调用它,用的着的时候使用,用不着的时候不使用,这就是回调方法。当以回调方法的形式来使用委托的时候,我们要做的是把委托类型的参数传进主调方法中去,被传进主调方法里的委托类型的参数的内部会封装着一个被回调的方法,即回调方法。主调函数会根据自己的逻辑来决定是不是调用这个回调方法。

/*==================模板方法====================*/
namespace delegate
{
  class program
    { 
     static void main(string[] args)
     {
      ProductFactory productFactory = new ProductFactory();
      WrapFactory wrapFactory = new WrapFactory();
     
      Func<Product> func1 = new Func<Product> (productFactory.MakePizza);
      Func<Product> func2 = new Func<Product> (productFactory.MakeToyCar);

     Box box1 = wrapFactory.WrapProduct(func1);
     Box box2 = wrapFactory.WrapProduct(func2);

     console.writeline(box1.Product.Name);
     console.writeline(box2.Product.Name);
      }
     }

  class Product
    {
     public string name{get;set;}
    }

  class Box
    {
     public Product product{get;set;}
    }

  class WrapFactory
    {
     public Box WrapFactory(Func<product> getproduct)
      {
       Box box = new Box();
       Product product = getproduct.invoke();
       box.Product = product;
       return box;
       }
    }


  class ProductFactory
    {
     public Product Makepizza()
      {
       Product product = new Product();
       product.name = "pizza";
       return product ;
       }
      public Product MakeToyCar()
      {
       Product product = new Product();
       product.name = "Toy Car";
       return product ;
       }
    }




}

模板方法的好处:
    Product类,Box类,WrapFactory类,都不需要修改,只需要不停的扩展产品工厂,那么就可以生产不同不样的产品。而且不管生产哪种产品的方法。 只要把这个方法封装在一个委托类型的对象里,传给我们的模板方法。我们的模板方法就一定能够把我的这个产品包装成一个箱子并交还回来。最大限度的重复使用代码
/*==================回调方法====================*/
namespace delegate
{
  class program
    { 
     static void main(string[] args)
     {
      ProductFactory productFactory = new ProductFactory();
      WrapFactory wrapFactory = new WrapFactory();
     
      Func<Product> func1 = new Func<Product> (productFactory.MakePizza);
      Func<Product> func2 = new Func<Product> (productFactory.MakeToyCar);
 
      Logger logger = new Logger();
      
      Action<Product> log = new Action<Product> (Logger.Log);
      

     Box box1 = wrapFactory.WrapProduct(func1 , log);
     Box box2 = wrapFactory.WrapProduct(func2 , log);

     console.writeline(box1.Product.Name);
     console.writeline(box2.Product.Name);
      }
     }


  class Logger
    {
     public void Log( Product product)
      {console.writeline("Product ‘{0}‘ created at ‘{1}‘ ,pizza is ‘{2}‘,product.name,datetime.now,product.pizza");}
    }

  class Product
    {
     public string name{get;set;}
     public string price{get;set;}
    }

  class Box
    {
     public Product product{get;set;}
    }

  class WrapFactory
    {
     public Box WrapFactory(Func<product> getproduct  ,   Action <Product> logcallback)
      {
       Box box = new Box();
       Product product = getproduct.invoke();
       if(product.Price>=50)
       {  logcallback(product); }
       box.Product = product;
       return box;
       }
    }


  class ProductFactory
    {
     public Product Makepizza()
      {
       Product product = new Product();
       product.name = "pizza";
       product.price = 12;
       return product ;
       }
      public Product MakeToyCar()
      {
       Product product = new Product();
       product.name = "Toy Car";
       product.price = 100;
       return product ;
       }
    }




}
  • 委托的高级使用

《C#入门详解》刘铁猛      delegate

/*=================多播委托====================*/
using system;
using system.collection.generic;
using system.threading;

namespace MulticastDelegateExample
{
    class program
      {
        Student stu1 = new Student(){ID =1,PenColor = ConsoleColor.Yellow};
        Student stu2 = new Student(){ID =2,PenColor = ConsoleColor.Green};
        Student stu3 = new Student(){ID =3,PenColor = ConsoleColor.Red};
     
        Action action1 = new Action(stu1.DoHomework);
        Action action2 = new Action(stu2.DoHomework);
        Action action3 = new Action(stu3.DoHomework);
  
       action1.invoke();//一个委托封装了一个方法的形式叫做单播委托
       action2.invoke();
       action3.invoke();


       action1 += action2;
       action2 += action3;
       action1.invoke();    //一个委托封装了多个方法的使用方式叫做多播委托

      }

      class Student
      {
        public int ID{get;set;}
        public ConsoleColor PenColor{get;set;}
        public void DoHomeWork()
         {
          console.ForegroundColor = this.PenColor;
          console.Writeline("student{0}doing homework{1}hours",this.ID, i);
          Thread.Sleep(1000);
          }
      }
}
/*=============使用接口来代替委托=======================
namespace delegate
{
  class program
    { 
     static void main(string[] args)
     {
      IproductFactory pizzaFactory = new PizzaFactory();
      IproductFactory toycarFactory = new ToyCarFactory();
      WrapFactory wrapFactory = new WrapFactory();
     

     Box box1 = wrapFactory.WrapProduct( pizzaFactory );
     Box box2 = wrapFactory.WrapProduct( toycarFactory );

     console.writeline(box1.Product.Name);
     console.writeline(box2.Product.Name);
      }
     }

      Interface IproductFactory
      { Product.Make();    }
    
      class PizzaFactory : IproductFactory
      {
       public Product Make()
        { 
           Product product = new Product();
           product.name = "pizza";
           return product ;
         }
       }
      class ToyCarFactory : IproductFactory
      {
       public Product Make()
        { 
           Product product = new Product();
           product.name = "Toy Car";
           return product ;
         }
       }
   


  class Product
    {
     public string name{get;set;}
    }

  class Box
    {
     public Product product{get;set;}
    }

  class WrapFactory
    {
     public Box WrapFactory(IproductFactory productFactory)
      {
       Box box = new Box();
       Product product = productFactory.Make();
       box.Product = product;
       return box;
       }
    }


}

 

《C#入门详解》刘铁猛 delegate

上一篇:C# socket 连接超时代码实现


下一篇:c#设计模式(5)——建造者模式