zoukankan      html  css  js  c++  java
  • C#委托初探

    委托是一种定义方法签名的类型,可以与具有兼容签名的任何方法关联。您可以通过委托调用其中已添加的方法列表。委托用于将方法作为参数传递给其他方法。事件处理程序就是通过委托调用的方法。您可以创建一个自定义方法,当发生特定事件时某个类(例如 Windows 控件)就可以调用您的方法。button的单击事件发生后,通过委托这个管道找到用户添加的处理方法,从而执行方法;不必像之前win32程序那样循环等待某个事件消息。

    先直接添端代码进来,

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 
     6 namespace Test_Delegate
     7 {
     8     //定义一个委托,对应方法签名为 int Fun(int , int )
     9     //编译器会自动生成一个委托类 dgOP,在此相当于声明一个类对象,稍后使用时new实例化
    10     //继承链如:Delegate:MulticastDelegate:Delegate:ICloneable,ISerializable
    11     public delegate int dgOP(int x, int y);
    12     //生成的类形如
    13     //sealed class dgOP : System.MulticastDelegate
    14     //{
    15     //    //构造函数,原理不清楚  !!
    16     //    public dgOP(object target,unit functionAddr);
    17     //    //成员函数,可在外调用
    18     //    public virtual int Invoke(int x, int y);  
    19     //    public virtual IAsyncResult BeginInvoke(int x, int y
    20     //        , AsyncCallback callback, object @object);
    21     //    public virtual int EndInvoke(IAsyncResult result);
    22     //}
    23     
    24     public class SimpleMath
    25     {
    26         /***********静态方法*******************/
    27         public static int Add(int x, int y)
    28         {
    29             Console.WriteLine("add");
    30             return x + y;
    31         }
    32         public static int Square(int x)
    33         {
    34             return x * x;
    35         }
    36         /***********动态方法*******************/
    37        
    38         public int Sub(int x, int y)
    39         {
    40             Console.WriteLine("sub");
    41             return x - y;
    42         }
    43     }
    44 
    45     class Program
    46     {
    47         static dgOP dg;
    48         static void Main(string[] args)
    49         {
    50             //静态方法
    51             //实例化上文中定义的(编译器自动生成的)委托类,并指定方法
    52             //+=内部隐式调用dgOP.Combine
    53             //Del(new dgOP(SimpleMath.Add));
    54             dg = dgOP.Combine(new dgOP(SimpleMath.Add),new dgOP(new SimpleMath().Sub)) as dgOP;
    55             //执行调用列表的函数,但最终只返回最后一个函数调用返回值。
    56             //dg(10 , 20)内部隐式调用 dg.Invoke(20 , 10)
    57             Tools.OutputParams(dg(10 , 20));
    58             Tools.OutputParams(dg.Invoke(20, 10));
    59             //DisplayDelegate(dg);
    60             Tools.NewLine();
    61 
    62             ////动态方法
    63             //SimpleMath m=new SimpleMath();
    64             //dgOP dg2 = new dgOP(m.Sub);
    65             //Tools.OutputParams(dg2(10,20),dg2.Invoke(20,10));
    66             //DisplayDelegate(dg2);
    67             ////委托已经声明为方法签名为:void Fun(int x,int y),对应2个参数
    68             ////SimpleMath.Square只含一个参数
    69             ////dgOP dg3 = new dgOP(SimpleMath.Square);
    70 
    71             Tools.Pause();
    72         }
    73 
    74         private static void Del(dgOP dgOP)
    75         {
    76             dg += dgOP;
    77         }
    78 
    79     
    80 
    81         private static dgOP Del()
    82         {
    83             dgOP dg = new dgOP(SimpleMath.Add);
    84             dg += new dgOP(new SimpleMath().Sub);
    85             return dg;
    86         }
    87 
    88         private static void DisplayDelegate(dgOP dg)
    89         {
    90             //输出委托列表内部的方法签名,类对象
    91             foreach (Delegate item in dg.GetInvocationList())
    92             {
    93                 Tools.OutputParams(item.Method, item.Target);
    94             }
    95         }
    96 
    97 
    98     }
    99 }

    Tools类只是个工具,用来输出值至控制台,或者另起一行,停止控制台。

    委托是最底层,事件是较上层,用来简化处理委托声明,封装维护调用列表。

      1 #region Using directives
      2 
      3 using System;
      4 using System.Collections.Generic;
      5 using System.Text;
      6 
      7 #endregion
      8 
      9 namespace CarEvents
     10 {
     11     class Program
     12     {
     13         static void Main(string[] args)
     14         {
     15             Console.WriteLine("***** Fun with Events *****
    ");
     16 
     17             // Make a car as usual. 
     18             Car c1 = new Car("SlugBug", 100, 10);
     19 
     20             // Register event handlers.
     21             c1.AboutToBlow += new Car.CarEventHandler(c1_AboutToBlow);
     22             c1.AboutToBlow += new Car.CarEventHandler(CarIsAlmostDoomed);
     23             c1.AboutToBlow += new Car.CarEventHandler(CarAboutToBlow);
     24 
     25             Car.CarEventHandler d = new Car.CarEventHandler(CarExploded);
     26             c1.Exploded += d;
     27 
     28             // Speed up (this will generate the events.)
     29             Console.WriteLine("***** Speeding up *****");
     30             for (int i = 0; i < 6; i++)
     31                 c1.Accelerate(20);
     32 
     33             // Remove CarExploded method 
     34             // from invocation list.
     35             c1.Exploded -= d;
     36 
     37             Console.WriteLine("
    ***** Speeding up *****");
     38             for (int i = 0; i < 6; i++)
     39                 c1.Accelerate(20);
     40 
     41             Console.ReadLine();
     42         }
     43 
     44         static void c1_AboutToBlow(string msg)
     45         {
     46             Console.WriteLine("xxxx");
     47         }
     48 
     49         public static void CarAboutToBlow(string msg)
     50         { Console.WriteLine(msg); }
     51 
     52         public static void CarIsAlmostDoomed(string msg)
     53         { Console.WriteLine("Critical Message from Car: {0}", msg); }
     54 
     55         public static void CarExploded(string msg)
     56         { Console.WriteLine(msg); }
     57 
     58     }
     59 }
     60 
     61 #region Using directives
     62 
     63 using System;
     64 using System.Collections.Generic;
     65 using System.Text;
     66 
     67 #endregion
     68 
     69 namespace CarEvents
     70 {
     71     public class Car
     72     {
     73         //// This delegate works in conjunction with the
     74         //// Car’s events.
     75         //public delegate void CarEventHandler(string msg);
     76 
     77         //// This car can send these events.
     78         //public event CarEventHandler Exploded;
     79         //public event CarEventHandler AboutToBlow;
     80 
     81         public delegate void CarEventHandler(string msg);
     82 
     83         public event CarEventHandler Exploded;
     84         public event CarEventHandler AboutToBlow;
     85         #region Basic Car members...
     86 
     87         #region Nested radio
     88         // Radio as nested type
     89         public class Radio
     90         {
     91             public void TurnOn(bool on)
     92             {
     93                 if (on)
     94                     Console.WriteLine("Jamming...");
     95                 else
     96                     Console.WriteLine("Quiet time...");
     97             }
     98         }
     99         #endregion
    100 
    101         // Internal state data.
    102         private int currSpeed;
    103         private int maxSpeed;
    104         private string petName;
    105 
    106         // Is the car alive or dead?
    107         bool carIsDead;
    108 
    109         // A car has-a radio.
    110         private Radio theMusicBox = new Radio();
    111 
    112         public Car()
    113         {
    114             maxSpeed = 100;
    115         }
    116 
    117         public Car(string name, int max, int curr)
    118         {
    119             currSpeed = curr;
    120             maxSpeed = max;
    121             petName = name;
    122         }
    123 
    124         public void CrankTunes(bool state)
    125         {
    126             theMusicBox.TurnOn(state);
    127         }
    128         #endregion
    129 
    130         #region Accelerate method
    131         public void Accelerate(int delta)
    132         {
    133             // If the car is dead, fire Exploded event.
    134             if (carIsDead)
    135             {
    136                 if (Exploded != null)
    137                     Exploded("Sorry, this car is dead...");
    138             }
    139             else
    140             {
    141                 currSpeed += delta;
    142 
    143                 // Almost dead?
    144                 if (10 == maxSpeed - currSpeed
    145                   && AboutToBlow != null)
    146                 {
    147                     AboutToBlow("Careful buddy!  Gonna blow!");
    148                 }
    149 
    150                 // Still OK!
    151                 if (currSpeed >= maxSpeed)
    152                     carIsDead = true;
    153                 else
    154                     Console.WriteLine("->CurrSpeed = {0}", currSpeed);
    155             }
    156         }
    157         #endregion
    158 
    159     }
    160 }
    View Code

    匿名方法是简化了委托及方法定义,不必再手动定义方法,直接间写在委托中。

      1 #region Using directives
      2 
      3 using System;
      4 using System.Collections.Generic;
      5 using System.Text;
      6 
      7 #endregion
      8 
      9 namespace AnonymousMethods
     10 {
     11     class Program
     12     {
     13         static void Main(string[] args)
     14         {
     15             Console.WriteLine("***** Anonymous Methods *****");
     16 
     17             int aboutToBlowCounter = 0;
     18 
     19             // Make a car as usual. 
     20             Car c1 = new Car("SlugBug", 100, 10);
     21 
     22             // Register event handlers as anonymous methods.          
     23             c1.AboutToBlow += delegate
     24             {
     25                 aboutToBlowCounter++;
     26                 Console.WriteLine("Eek!  Going too fast!");
     27             };
     28 
     29             c1.AboutToBlow += delegate(object sender, CarEventArgs e)
     30             {
     31                 aboutToBlowCounter++;
     32                 Console.WriteLine("Message from Car: {0}", e.msg);
     33             };
     34 
     35             c1.Exploded += delegate(object sender, CarEventArgs e)
     36             { Console.WriteLine("Message from Car: {0}", e.msg); };
     37 
     38             // Speed up (this will generate the events.)
     39             Console.WriteLine("
    ***** Speeding up *****");
     40             for (int i = 0; i < 6; i++)
     41                 c1.SpeedUp(20);
     42 
     43             Console.WriteLine("AboutToBlow event was fired {0} times",
     44               aboutToBlowCounter);
     45 
     46             Console.ReadLine();
     47         }
     48     }
     49 }
     50 #region Using directives
     51 
     52 using System;
     53 using System.Collections.Generic;
     54 using System.Text;
     55 
     56 #endregion
     57 
     58 namespace AnonymousMethods
     59 {
     60    //与上面的事件代码类似     
     61     public class CarEventArgs : EventArgs
     62     {
     63         public readonly string msg;
     64         public CarEventArgs(string message)
     65         {
     66             msg = message;
     67         }
     68     }
     69 
     70     public class Car
     71     {
     72         // This delegate works in conjunction with the
     73         // Car’s events.
     74         public delegate void CarEventHandler(object sender, CarEventArgs e);
     75 
     76         // This car can send these events.
     77         public event CarEventHandler Exploded;
     78         public event CarEventHandler AboutToBlow;
     79 
     80         #region Basic Car members...
     81         #region Nested radio
     82         // Radio as nested type
     83         public class Radio
     84         {
     85             public void TurnOn(bool on)
     86             {
     87                 if (on)
     88                     Console.WriteLine("Jamming...");
     89                 else
     90                     Console.WriteLine("Quiet time...");
     91             }
     92         }
     93         #endregion
     94 
     95         // Internal state data.
     96         private int currSpeed;
     97         private int maxSpeed;
     98         private string petName;
     99 
    100         // Is the car alive or dead?
    101         bool carIsDead;
    102 
    103         // A car has-a radio.
    104         private Radio theMusicBox = new Radio();
    105 
    106         public Car()
    107         {
    108             maxSpeed = 100;
    109         }
    110 
    111         public Car(string name, int max, int curr)
    112         {
    113             currSpeed = curr;
    114             maxSpeed = max;
    115             petName = name;
    116         }
    117 
    118         public void CrankTunes(bool state)
    119         {
    120             theMusicBox.TurnOn(state);
    121         }
    122 #endregion 
    123 
    124         public void SpeedUp(int delta)
    125         {
    126             // If the car is dead, fire Exploded event.
    127             if (carIsDead && Exploded != null)
    128             {
    129                 Exploded(this, new CarEventArgs("Sorry, this car is dead..."));
    130             }
    131             else
    132             {
    133                 currSpeed += delta;
    134 
    135                 // Almost dead?
    136                 if (10 == maxSpeed - currSpeed
    137                     && AboutToBlow != null)
    138                 {
    139                     AboutToBlow(this, new CarEventArgs("Careful buddy!  Gonna blow!"));
    140                 }
    141 
    142                 // Still OK!
    143                 if (currSpeed >= maxSpeed)
    144                     carIsDead = true;
    145                 else
    146                     Console.WriteLine("->CurrSpeed = {0}", currSpeed);
    147             }
    148         }
    149     }
    150 }
    View Code

    而lambdar表达式则是对匿名方法的再次简化,由此可以引申出linq,ef的语法。

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 
     6 namespace SimpleLambdaExpressions
     7 {
     8   class Program
     9   {
    10     static void Main(string[] args)
    11     {
    12       Console.WriteLine("***** Fun with Lambdas *****
    ");
    13       TraditionalDelegateSyntax();
    14       AnonymousMethodSyntax();
    15       
    16       Console.WriteLine();
    17       LambdaExpressionSyntax();
    18 
    19       Console.ReadLine();
    20     }
    21 
    22     #region Traditional delegate syntax
    23     static void TraditionalDelegateSyntax()
    24     {
    25       // Make a list of integers.
    26       List<int> list = new List<int>();
    27       list.AddRange(new int[] { 20, 1, 4, 8, 9, 44 });
    28 
    29       // Call FindAll() using traditional delegate syntax.
    30       Predicate<int> callback = new Predicate<int>(IsEvenNumber);
    31       List<int> evenNumbers = list.FindAll(callback);
    32 
    33       Console.WriteLine("Here are your even numbers:");
    34       foreach (int evenNumber in evenNumbers)
    35       {
    36         Console.Write("{0}	", evenNumber);
    37       }
    38       Console.WriteLine();
    39     }
    40     // Target for the Predicate<> delegate.
    41     static bool IsEvenNumber(int i)
    42     {
    43       // Is it an even number?
    44       return (i % 2) == 0;
    45     }
    46     #endregion 
    47 
    48     #region Anonymous method syntax
    49     static void AnonymousMethodSyntax()
    50     {
    51       // Make a list of integers using C# 3.0
    52       // collection initialization syntax. 
    53       List<int> list = new List<int>();
    54       list.AddRange(new int[] { 20, 1, 4, 8, 9, 44 });
    55 
    56       List<int> evenNumbers = list.FindAll(
    57         delegate(int i)
    58         {
    59           return (i % 2) == 0;
    60         }
    61       );
    62 
    63       Console.WriteLine("Here are your even numbers:");
    64       foreach (int evenNumber in evenNumbers)
    65       {
    66         Console.Write("{0}	", evenNumber);
    67       }
    68       Console.WriteLine();
    69     }
    70     #endregion
    71 
    72     #region Lambda expression syntax
    73     static void LambdaExpressionSyntax()
    74     {
    75       // Make a list of integers. 
    76       List<int> list = new List<int>();   
    77       list.AddRange(new int[] { 20, 1, 4, 8, 9, 44 });
    78 
    79       // Now process each argument within a group of 
    80       // code statements.
    81       List<int> evenNumbers = list.FindAll((i) => 
    82       { 
    83         Console.WriteLine("value of i is currently: {0}", i);
    84         bool isEven = ((i % 2) == 0);
    85         return isEven;
    86       });
    87 
    88       Console.WriteLine("Here are your even numbers:");
    89       foreach (int evenNumber in evenNumbers)
    90       {
    91         Console.Write("{0}	", evenNumber);
    92       }
    93       Console.WriteLine();
    94     }
    95     #endregion
    96   }
    97 }
    View Code

    总结性的比较少,代码比较多。因为我还没有完全领悟,只是初步了解了下。

    具体大家可以发挥google的优势。

  • 相关阅读:
    FreeMarker中<#include>和<#import>标签的区别
    freemarker自定义标签(与java合用)
    JSP页面中验证码的调用方法
    js关闭或者刷新页面后执行事件
    动态生成能够局部刷新的验证码【AJAX技术】---看了不懂赔你钱
    Delphi中Indy 10的安装和老版本的卸载
    在Delphi中关于UDP协议的实现
    Easy smart REST with kbmMW
    Delphi事件的广播
    js调用跨域
  • 原文地址:https://www.cnblogs.com/nlh774/p/3501319.html
Copyright © 2011-2022 走看看