文章目录
- 委托
- 自定义委托
- 模板方法(工厂模式
- 回调(callback)函数(观察者模式
- 多播(multicast)委托
- 委托的高级使用
- 使用接口 重构 模板方法代码
- 注意
- 参考
委托
委托(delegate)是一种类型,定义了一种方法签名,因此可以将方法作为参数进行传递。
委托类似于 C++ 中的函数指针,但比函数指针更加安全和灵活。
使用委托,可以实现事件处理、回调函数等功能。
建议:使用接口取代委托
- Action
- 无参无返回
- Func
- 有参有返回
Calaculator calaculator = new Calaculator();
// Action
new Action(calaculator.Report).Invoke();
// Func
Func<int, int, int> func1 = new Func<int, int, int>(calaculator.Add);
Func<int, int, int> func2 = new Func<int, int, int>(calaculator.Sub);
int x = 100;
int y = 200;
int z = 0;
// 可以省略invoke
z = func1(x, y);
Console.WriteLine(z);
z = func2.Invoke(x, y);
Console.WriteLine(z);
class Calaculator {
public void Report()
{
Console.WriteLine("i have 3 methods");
}
public int Add(int a, int b)
{
return a + b;
}
public int Sub(int a, int b)
{
return a - b;
}
}
自定义委托
// 与类平级,放到类中属于嵌套
public delegate double Calc(double x,double y);
internal class Program
{
static void Main(string[] args)
{
Calaculator calaculator = new Calaculator();
Calc calc1 = new Calc(calaculator.Add1);
Calc calc2 = new Calc(calaculator.Mul);
double x = 100;
double y = 100;
double z = 0;
z = calc1.Invoke(x, y);
Console.WriteLine(z);
z = calc2.Invoke(x, y);
Console.WriteLine(z);
}
}
模板方法(工厂模式
”借用“指定的外部方法来产生结果 , 提高对代码的复用
ProductFactory()
只需要扩展这个方法,其他方法都不用动
static void Main(string[] args)
{
ProductFactory productFactory = new ProductFactory();
WrapFactory wrapFactory = new WrapFactory();
Func<Product> func1 = new Func<Product>(productFactory.MakeToy);
Func<Product> func2 = new Func<Product>(productFactory.MakePizza);
Box box1 = wrapFactory.WrapProduct(func1);
Box box2 = wrapFactory.WrapProduct(func2);
Console.WriteLine(box1.Product.Name);
Console.WriteLine(box2.Product.Name);
}
}
class Product() {
public string Name { get; set; }
}
class Box() {
public Product Product { get; set; }
}
class WrapFactory {
public Box WrapProduct(Func<Product> getProduct) {
Box box = new Box();
// invoke 执行拿到产品(不用管是什么产品
Product product = getProduct.Invoke();
box.Product = product;
return box;
}
}
class ProductFactory() {
public Product MakePizza() {
Product product = new Product();
product.Name = "Pizza";
return product;
}
public Product MakeToy() {
Product product = new Product();
product.Name = "Toy";
return product;
}
}
回调(callback)函数(观察者模式
调用指定的外部方法
在模板方法基础上添加
internal class Program
{
static void Main(string[] args)
{
ProductFactory productFactory = new ProductFactory();
WrapFactory wrapFactory = new WrapFactory();
Func<Product> func1 = new Func<Product>(productFactory.MakeToy);
Func<Product> func2 = new Func<Product>(productFactory.MakePizza);
Logger logger = new Logger();
Action<Product> action = new Action<Product>(logger.Log);
Box box1 = wrapFactory.WrapProduct(func1,action);
Box box2 = wrapFactory.WrapProduct(func2,action);
Console.WriteLine(box1.Product.Name);
Console.WriteLine(box2.Product.Name);
}
}
class Logger {
public void Log(Product product) {
//DateTime.UtcNow 无时区时间 ; DateTime.Now 有时区
Console.WriteLine("Product '{0}' created 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 WrapProduct(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 MakeToy() {
Product product = new Product();
product.Name = "Toy";
product.Price=120;
return product;
}
}
多播(multicast)委托
委托的高级使用
使用接口 重构 模板方法代码
直接用接口,不使用委托。
方法形参为接口,类继承接口,new不同的类传进同个方法
internal class Program
{
static void Main(string[] args)
{
WrapFactory wrapFactory = new WrapFactory();
Logger logger = new Logger();
Action<Product> action = new Action<Product>(logger.Log);
Box box1 = wrapFactory.WrapProduct(new PizzaFactory());
Box box2 = wrapFactory.WrapProduct(new ToyCarFactory());
Console.WriteLine(box1.Product.Name);
Console.WriteLine(box2.Product.Name);
}
}
interface IProductFactory {
Product Make();
}
class PizzaFactory : IProductFactory
{
public Product Make()
{
Product product = new Product();
product.Name = "Pizza";
product.Price = 12;
return product;
}
}
class ToyCarFactory : IProductFactory
{
public Product Make()
{
Product product = new Product();
product.Name = "Toy";
product.Price = 120;
return product;
}
}
class WrapFactory {
public Box WrapProduct(IProductFactory productFactory) {
Box box = new Box();
Product product = productFactory.Make();
box.Product = product;
return box;
}
}
}
注意
委托:
参考
刘铁猛——C#