委托是什么?如何使用?
委托是一种类,类是数据类型所以委托也是一种数据类型,它的声明方式与一般的类不同,主要是为了照顾可读性和C/C++,委托使用要慎之又慎
C#有已经定义好的两种委托方式,一个是Action,一个是Func,Action是无返回值的,而Func是要求有返回值的,两者都通过泛型定义好了参数类型,上限为16个。详细用法如下代码所示。此外还有predicate,返回值为bool类型。
此外C#中还有自定义的委托,需要使用delegate关键字来定义
需要注意声明委托的位置,因为委托也是一种类,所以声明位置应当是与命名空间下,与其他类同级
委托与所封装的方法必须类型兼容,即返回值的数据类型一致,参数列表在个数和数据类型上一致(参数名不需要一样),具体代码如下所示。
delegate int delegateMethod(int x,int y );
class Program
{
static void Main(string[] args)
{
Calculator cal = new Calculator();
delegateMethod dm = new delegateMethod(cal.Add);
int a = 1; int b = 2; int c = 0;
c = dm(a,b);
Console.WriteLine(c);
Action action = new Action(cal.report);
Action<int, int> actiondetail = new Action<int, int>(cal.reportdetail);
Func<int, int, int> func = new Func<int, int, int>(cal.Add);
action();
actiondetail(a, b);
c = func(a, b);
Console.WriteLine(c);
}
public class Calculator {
public int Add(int x,int y)
{
return x + y;
}
public int Sub(int x,int y)
{
return x - y;
}
public void report()
{
Console.WriteLine("this is a calculator");
}
public void reportdetail(int x,int y)
{
Console.WriteLine("process "+x+"+"+y+" is calculating...");
}
}
委托的一般使用(把方法当作参数传给另一个方法)
1.借用指定的外部方法来产生结果(委托有返回值),如下例中委托func1和func2来调用产品工厂productFactory中的制造产品方法
2.调用指定的外部方法[回调](委托没有返回值),如下例中当产品被包装时,由于触发价格判断,调用logger打出此时的商品详情。
using System;
using System.Collections.Generic;
using System.Text;
namespace Helloworld
{
class DelegateExample
{
static void Main(string[] args)
{
ProductFactory productFactory = new ProductFactory();
WrapFactoy wrapFactoy = new WrapFactoy();
Func<Product> func1 = new Func<Product>(productFactory.MakePizza);
Func<Product> func2 = new Func<Product>(productFactory.MakeToy);
Action<Product> action = new Action<Product>(new Logger().log);
Box box1 = wrapFactoy.WrapProduct(func1,action);
Box box2 = wrapFactoy.WrapProduct(func2,action);
Console.WriteLine(box1.product.name);
Console.WriteLine(box2.product.name);
}
}
class Product
{
public string name { get; set; }
public double price { get; set; }
}
class Logger
{
public void log(Product product)
{
Console.WriteLine("Product '{0}' created at {1}. Price is {2} ", product.name, DateTime.UtcNow, product.price);
}
}
class Box
{
public Product product { get; set; }
}
class WrapFactoy
{
public Box WrapProduct(Func<Product> getProduct,Action<Product> action)
{
Box box = new Box();
Product product = getProduct();
if (product.price > 0)
{
action(product);
}
box.product = product;
return box;
}
}
class ProductFactory
{
public Product MakePizza()
{
Product product = new Product();
product.name = "Pizza";
product.price = 15;
return product;
}
public Product MakeToy()
{
Product product = new Product();
product.name = "Toy";
product.price = 45;
return product;
}
}
}