zoukankan      html  css  js  c++  java
  • 委托

    最简单的委托示例:

     1 // 该委托可以指向任何传入两个整数并返回一个整数的方法
     2     public delegate int BinaryOp( int x, int y );
     3     public class SimpleMath
     4     {
     5         public int Add( int x, int y )
     6         { return x + y; }
     7         public int Subtract( int x, int y )
     8         { return x - y; }
     9         public static int SquareNumber( int a )
    10         { return a * a; }
    11     } 
    12     class Program
    13     {
    14         static void Main( string[] args )
    15         {
    16             Console.WriteLine("***** Simple Delegate Example *****
    ");
    17 
    18             SimpleMath m = new SimpleMath();
    19 
    20             BinaryOp b = new BinaryOp(m.Add);
    21             DisplayDelegateInfo(b);
    22       
    23             Console.WriteLine("10 + 10 is {0}", b(10, 10));
    24 
    25             Console.ReadLine();
    26         }    
    27         static void DisplayDelegateInfo( Delegate delObj )
    28         {           
    29             foreach (Delegate d in delObj.GetInvocationList())
    30             {
    31                 Console.WriteLine("Method Name: {0}", d.Method);
    32                 Console.WriteLine("Type Name: {0}", d.Target);
    33             }
    34         }      
    35     }

    支持多路广播的委托示例:

     1 /*
     2  * 2015.5
     3  * Car.cs
     4  */
     5 using System;
     6 using System.Collections.Generic;
     7 using System.Linq;
     8 using System.Text;
     9 using System.Threading.Tasks;
    10 
    11 namespace CarDelegate
    12 {
    13     public class Car
    14     {
    15         // 内部状态数据
    16         public int CurrentSpeed { get; set; }
    17         public int MaxSpeed { get; set; }
    18         public string PetName { get; set; }
    19         private bool carIsDead = false;
    20 
    21         // 构造函数
    22         public Car() { MaxSpeed = 180; }
    23         public Car( string name, int maxSp, int currSp )
    24         {
    25             CurrentSpeed = currSp;
    26             MaxSpeed = maxSp;
    27             PetName = name;
    28         }
    29      
    30         // 定义委托类型
    31         public delegate void CarEngineHandler( string msgForCaller );
    32 
    33         // 定义每个委托类型的成员变量
    34         private CarEngineHandler listOfHandlers;
    35 
    36         // 添加注册函数
    37         public void RegisterWithCarEngine( CarEngineHandler methodToCall )
    38         {   // 给每个委托对象添加多个方法
    39             // 支持多路广播,可以使用 +=操作符,或直接调用Delegate.Combine()
    40 
    41             // listOfHandlers += methodToCall; 
    42 
    43             if (listOfHandlers == null)
    44                 listOfHandlers = methodToCall;
    45             else
    46                 Delegate.Combine(listOfHandlers, methodToCall);
    47         }
    48 
    49         public void UnRegisterWithCarEngine( CarEngineHandler methodToCall )
    50         {   // 从委托的调用列表移除成员, 也可调用 Delegate.Remove()
    51 
    52             listOfHandlers -= methodToCall;
    53         }
    54    
    55         public void Accelerate( int delta )
    56         {        
    57             if (carIsDead)
    58             {
    59                 if (listOfHandlers != null)
    60                     listOfHandlers("Sorry, this car is dead...");
    61             }
    62             else
    63             {
    64                 CurrentSpeed += delta;
    65                 if (10 == (MaxSpeed - CurrentSpeed)
    66                     && listOfHandlers != null)
    67                 {
    68                     listOfHandlers("Careful buddy!");
    69                 }
    70                 if (CurrentSpeed >= MaxSpeed)
    71                     carIsDead = true;
    72                 else
    73                     Console.WriteLine("CurrentSpeed = {0}", CurrentSpeed);
    74             }
    75         }
    76     }
    77 }
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace CarDelegate
     8 {
     9     class Program
    10     {
    11         static void Main( string[] args )
    12         {
    13             Console.WriteLine("***** Delegates as event enablers *****
    ");
    14 
    15             Car c1 = new Car("BMW", 100, 10);
    16                       
    17             // 先绑定委托对象,稍后再注销
    18             Car.CarEngineHandler handler2 = new Car.CarEngineHandler(OnCarEngineEvent2);
    19             c1.RegisterWithCarEngine(handler2);
    20 
    21             Console.WriteLine("***** Speeding up 1*****");
    22             for (int i = 0; i < 6; i++)
    23                 c1.Accelerate(20);
    24 
    25             c1.UnRegisterWithCarEngine(handler2);
    26 
    27             // 注销上一种方法,注册另一种方法
    28             // 观察到两种方法的输出不一样
    29             c1.RegisterWithCarEngine(new Car.CarEngineHandler(OnCarEngineEvent));
    30             Console.WriteLine("***** Speeding up 2*****");
    31             for (int i = 0; i < 6; i++)
    32                 c1.Accelerate(20);
    33 
    34             Console.ReadLine();
    35         }
    36      
    37         public static void OnCarEngineEvent( string msg )
    38         {
    39             Console.WriteLine("
    ***** Message From Car Object *****");
    40             Console.WriteLine("=> {0}", msg);
    41             Console.WriteLine("***********************************
    ");
    42         }
    43 
    44         public static void OnCarEngineEvent2( string msg )
    45         {
    46             Console.WriteLine("=> {0}", msg.ToUpper());
    47         }
    48     }
    49 }

    泛型Action<>和Func<>委托示例:

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace ActionAndFuncDelegates
     8 {
     9     class Program
    10     {
    11         static void Main(string[] args)
    12         {
    13             Console.WriteLine("***** Fun with Action and Func *****
    ");
    14 
    15             // 使用泛型 Action<> 委托来指向DisplayMessage, Action<>可以指向多至16个参数
    16             Action<string, ConsoleColor, int> actionTarget = 
    17                 new Action<string, ConsoleColor, int>(DisplayMessage);
    18 
    19             actionTarget("Action Message!", ConsoleColor.Green, 5);
    20 
    21             // 使用泛型 Func<> 委托
    22             Func<int, int, int> funcTarget = new Func<int, int, int>(Add);
    23             int result = funcTarget.Invoke(40, 40);
    24             Console.WriteLine("40 + 40 = {0}", result);
    25 
    26             Func<int, int, string> funcTarget2 = new Func<int, int, string>(SumToString);
    27             string sum = funcTarget2(90, 300);
    28             Console.WriteLine(sum);
    29 
    30             Console.ReadLine();
    31         }
    32 
    33         static void DisplayMessage(string msg, ConsoleColor txtColor, int printCount)
    34         {
    35             // 设置命令行文本颜色 
    36             ConsoleColor previous = Console.ForegroundColor;
    37             Console.ForegroundColor = txtColor;
    38 
    39             for (int i = 0; i < printCount; i++)
    40             {
    41                 Console.WriteLine(msg);
    42             }
    43             // 重置颜色 
    44             Console.ForegroundColor = previous;
    45         }
    46       
    47         static int Add(int x, int y)
    48         {
    49             return x + y;
    50         }
    51 
    52         static string SumToString(int x, int y)
    53         {
    54             return (x + y).ToString();
    55         }
    56     }
    57 }

    在事件注册时直接将一个委托与一段代码相关联称为匿名方法。使用 +=语法处理事件时被内联定义。

    如:  
    Car c1 = new Car("BMW", 100, 10);
    c1.AboutToBlow += delegate(object sender, CarEventArgs e)
    {
         aboutToBlowCounter++;
             Console.WriteLine("Message from Car: {0}", e.msg);
    };
     
    C#的Lambda 表达式都使用 Lambda 运算符 =>,该运算符读为“goes to”。语法如下:
    形参列表=>函数体
    函数体多于一条语句的可用大括号括起。
    Lambda 表达式可以用于任何匿名方法或者强类型委托可以应用的场合,而且比匿名方法更节省编码时间。其实编译器只是把表达式编译为使用委托Predicate<T>的标准匿名方法而已。
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace LambdaExpressionsMultipleParams
     8 {
     9     public class SimpleMath
    10     {
    11         // 多个参数
    12         public delegate void MathMessage( string msg, int result );
    13         private MathMessage mmDelegate;
    14 
    15         public void SetMathHandler( MathMessage target )
    16         { mmDelegate = target; }
    17 
    18         public void Add( int x, int y )
    19         {
    20             if (mmDelegate != null)
    21                 mmDelegate.Invoke("Adding has completed!", x + y);
    22         }
    23     }
    24 
    25     class Program
    26     {
    27         static void Main( string[] args )
    28         {
    29             // 使用Lambda表达式注册委托
    30             SimpleMath m = new SimpleMath();
    31             m.SetMathHandler(( msg, result ) =>
    32             { Console.WriteLine("Message: {0}, Result: {1}", msg, result); });
    33 
    34             // 执行Lambda表达式
    35             m.Add(10, 10);
    36             Console.ReadLine();
    37         }
    38     }
    39 }
  • 相关阅读:
    POJ 3258 (NOIP2015 D2T1跳石头)
    POJ 3122 二分
    POJ 3104 二分
    POJ 1995 快速幂
    409. Longest Palindrome
    389. Find the Difference
    381. Insert Delete GetRandom O(1)
    380. Insert Delete GetRandom O(1)
    355. Design Twitter
    347. Top K Frequent Elements (sort map)
  • 原文地址:https://www.cnblogs.com/ht-beyond/p/4472480.html
Copyright © 2011-2022 走看看