个人感觉和java的反射类相似
action委托 实例化该对象时,传入一个方法,后面就可以直接用action.Invoke()或者action()调用该方法 注意:这种委托只能获取无返回值的方法
Func委托 Func<原方法的参数列表类型….,返回值类型> 总之泛型列表的个数就是原方法参数列表的个数+1
自定义委托
public delegate 目标方法的返回值类型 委托名(目标方法的参数列表); 声明委托的位置尽量放在和其他类的同一层,如果不小心声明到其他类里面,则可以通过类.声明委托类来进行使用
委托的一般使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace OrderTest { internal class Program { static void Main (string [] args ) { MyFactory myFactory = new MyFactory(); ProductFactory productFactory = new ProductFactory(); Func<Product> func1 = new Func<Product>(productFactory.Car); Func<Product> func2 = new Func<Product>(productFactory.Dog); Box box1 = myFactory.WrapProduct(func1); Box box2 = myFactory.WrapProduct(func2); } } class Product { public string Name { get ; set ; } } class Box { public Product Product { get ; set ; } } class MyFactory { public Box WrapProduct (Func<Product> getProduct ) { Box box = new Box(); Product product = getProduct(); box.Product = product; return box; } } class ProductFactory { public Product Car () { Product product = new Product(); product.Name = "Car" ; return product; } public Product Dog () { Product product = new Product(); product.Name = "Dog" ; return product; } } }
给上述代码添加回调函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace OrderTest { internal class Program { static void Main (string [] args ) { MyFactory myFactory = new MyFactory(); ProductFactory productFactory = new ProductFactory(); Action<Product> log = new Action<Product>(Logger.Log); Func<Product> func1 = new Func<Product>(productFactory.Car); Func<Product> func2 = new Func<Product>(productFactory.Dog); Box box1 = myFactory.WrapProduct(func1,log); Box box2 = myFactory.WrapProduct(func2, log); } } class Product { public string Name { get ; set ; } public int Price { get ; set ; } } class Box { public Product Product { get ; set ; } } class MyFactory { public Box WrapProduct (Func<Product> getProduct,Action<Product> logProduct ) { Box box = new Box(); Product product = getProduct(); if (product.Price >= 10 ) { logProduct(product); } box.Product = product; return box; } } class Logger { public static void Log (Product product ) { Console.WriteLine("{0},{1},{2}" , product.Name, DateTime.UtcNow, product.Price); } } ... }
无论是模板方法还是回调方法,都是通过传入一个委托类型的参数,封装了一个外部的方法
委托的高级使用
多播委托 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace HighOrder { internal class Program { static void Main (string [] args ) { Student student1 = new Student() {Id = 2 , penColor = ConsoleColor.Yellow}; Student student2 = new Student() { Id = 4 , penColor = ConsoleColor.Blue }; Student student3 = new Student() { Id = 23 , penColor = ConsoleColor.Green }; Action action1 = new Action(student1.printInformation); Action action2 = new Action(student1.printInformation); Action action3 = new Action(student1.printInformation); action1 += action2; action1(); Console.ReadKey(); } } class Student { public int Id { get ; set ; } public ConsoleColor penColor { get ; set ; } public void printInformation () { Console.WriteLine(DateTime.UtcNow); } } }
异步调用 隐式的异步调用 主线程
1 2 3 4 5 6 7 action1.BeginInvoke(null ,null ); for (int i = 0 ; i < 10 ; i++){ Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine("thread{0}" , i); Thread.Sleep(1000 ); }
action1实现的程序
1 2 3 4 5 6 for (int i = 0 ; i < 2 ; i++){ Console.ForegroundColor = this .penColor; Console.WriteLine(DateTime.UtcNow); Thread.Sleep(1000 ); }
委托变量使用BeginInvoke方法时,可以实现隐式的异步调用
显式的异步调用
创建多个线程去运行方法
使用Task运行方法