委托
是C/C++函数指针的升级,方法的间接调用(寻址,方法的首地址)。
//使用Action(),Func()执行委托
static void Main()
{
Counter counter = new Counter();
//Action:可间接执行不带参的方法
Action action = new Action(counter.Report);
action.Invoke();//委托启动方法1
action();//委托启动方法2
//Func: 可间接执行无参有返回值或有参有返回值的方法
Func<int,int,int>func1 = new Func<int,int,int>(counter.Add);
int x=5,y=10,z=0;
Conssole.WriteLine(func1.Invoke(x,y););
z = func1(x,y);
}
class Counter
{
public void Report()
{
Console.WriteLine("Method is running");
}
public int Add(int a,int b)
{
return a+b;
}
}
委托的声明(自定义委托)
委托是一种类,类是数据类型所以委托也是一种数据类型,声明委托在Program类外;
C#允许类的嵌套
public delegate double Calc(double a, double b);
//使用域public 委托类型delegate 返回值类型double 委托名称Calc (目标方法参数列表);
internal class Program
{
static void Main()
{
Counter counter = new Counter();
Calc calc = new Calc(counter.Plus);
calc += counter.Plus;//一个委托挂钩多个方法
double a=5,b=10,c=0;
Console.WriteLine(calc.Invoke(a,b));
c = clac(a,b)
Console.WriteLine(c);
}
class Counter
{
public double Puls(double a,double b)
{
return a*b;
}
}
}
委托的应用
(通过委托把方法当做参数传给另一个方法)
1. 模板方法
借用指定的外部方法产生结果,委托有返回值,Func
2. 回调方法callback
调用指定的外部方法,委托无返回值,Action
static void Main(string[] args)
{
ProductFactory productFactory = new ProductFactory();
WrapFactory wrapFactory = new WrapFactory();
Logger logger = new Logger();
Func<Product> func1 = new Func<Product>(productFactory.MakePizza);
Func<Product> func2 = new Func<Product>(productFactory.MaketoyCar);
Action<Product> log = new Action<Product>(logger.Log);
Box box1 = wrapFactory.WarpProduct(func1,log);
Box box2 = wrapFactory.WarpProduct(func2, log);
Console.WriteLine(box1.Product.Name);
Console.WriteLine(box2.Product.Name);
Console.ReadKey();
}
class Logger
{
public void Log(Product product)
{
//回调方法,无返回值,程序运行时查看程序状态
Console.WriteLine("Product '{0}'create at {1}. Price is {2}",product.Name,DateTime.UtcNow,product.Price);
}
}
class Product
{
public string Name { get; set; }
public double Price { get; set; }
}
class Box
{
public Product Product { get; set; }
}
class WrapFactory
{
public Box WarpProduct(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 = 60;
return product;
}
}
Logger类常用于程序运行时查看程序状态,用于回调的方法,无返回值。