委托

最简单的委托示例:

 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 *****\n");
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 *****\n");
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("\n***** Message From Car Object *****");
40             Console.WriteLine("=> {0}", msg);
41             Console.WriteLine("***********************************\n");
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 *****\n");
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 }

 

posted @ 2015-05-02 20:44  ht-beyond  阅读(167)  评论(0编辑  收藏  举报