委托(1)


函数指针

请添加图片描述
在这里插入图片描述
在这里插入图片描述

using System;
using System.Collections.Generic;

using System.Windows.Forms;
namespace NamespaceEncasement

{
    class Program
    {
        static void Main(string[] args)
        {
            Calculator c = new Calculator();
            Action action = new Action(c.Report);//在这里Report后面没有(),说明这里是想用它的方法名,不是要调用这个方法。
              //直接调用Report这个方法
            c.Report();
            //间接调用Report这个方法
            action.Invoke();
//第三种方法
            action();
            Console.ReadKey();
        }



    }
    class Calculator

    {
        public void Report()
        {
            Console.WriteLine("I have 3 methods");

        }

    }
}

上述代码可以直接打印

委托的简单使用里面有Action​委托和Func​委托

如果要调用Calculator类的另外两个方法,用Func委托

using System;
using System.Collections.Generic;

using System.Windows.Forms;
namespace NamespaceEncasement

{
    class Program
    {
        static void Main(string[] args)
        {
            Calculator c = new Calculator();
            Action action = new Action(c.Report);//在这里Report后面没有(),说明这里是想用它的方法名,不是要调用这个方法。
              //直接调用Report这个方法
            c.Report();
            //间接调用Report这个方法
            action.Invoke();
            //第三种方法
            action();
            Func<int, int, int> func1 = new Func<int, int, int>(c.Add);
            Func<int, int, int> func2 = new Func<int, int, int>(c.Sub);
            int x = 100;
            int y = 200;
            int z = 0;
            z = func1.Invoke(x,y);
            Console.WriteLine(z);
            z = func2.Invoke(x,y);
            Console.WriteLine(z);
                Console.ReadKey();
        }



    }
    class Calculator

    {
        public void Report()
        {
            Console.WriteLine("I have 3 methods");

        }
        public int Sub(int a, int b)
        {
            int result = a - b;
            return result;
        }
        public int Add(int a, int b)
        {
            int result = a + b;
            return result;
        }
    }
}

当然也可以直接调用

 int x = 100;
            int y = 200;
            int z = 0;
            z = func1(x,y);
            Console.WriteLine(z);
            z = func2(x,y);
            Console.WriteLine(z);

委托的声明(自定义委托)

在这里插入图片描述

注意委托是一个类,所以理论上和Class Program是平级的,应该写到Class Program外面。另外注意,可以仿照指针的形式把类似c = calc1.Invoke(a, b);语句中的Invoke去掉。

using System;
using System.Collections.Generic;

using System.Windows.Forms;
namespace NamespaceEncasement

{
    public delegate double Calc(double x, double y);
    class Program
    {
        static void Main(string[] args)
        {
            Calculator calculator = new Calculator();
            Calc calc1 = new Calc(calculator.Add);
            Calc calc2 = new Calc(calculator.Sub);
            Calc calc3 = new Calc(calculator.Mul);
            Calc calc4 = new Calc(calculator.Div);
            double a = 100;
            double b = 200;
            double c;
            c = calc1.Invoke(a, b);
            Console.WriteLine(c);
            c = calc2.Invoke(a, b);
            Console.WriteLine(c);
            c = calc3.Invoke(a, b);
            Console.WriteLine(c);
            c = calc4.Invoke(a, b);
            Console.WriteLine(c);
            Console.ReadKey();
        }
    }
    class Calculator

    {
  
        public double Sub(double a, double b)
        {
            double result = a - b;
            return result;
        }
        public double Add(double a, double b)
        {
            double result = a + b;
            return result;
        }
        public double Mul(double a, double b)
        {
            double result = a * b;
            return result;
        }
        public double Div(double a, double b)
        {
            double result = a/b;
            return result;
        }
    }
}

当然,C# 本身可以嵌套,也就说类里面还可以创建类,那么如果类里面创建了委托,使用该委托的时候,应该在委托前面加上类名.

在这里插入图片描述

模板方法

模板方法的好处是,只需要在一个类里面增加产品,其余的类都不用动,然后通过其中一个类来调用委托即可

using System;
using System.Collections.Generic;

using System.Windows.Forms;
namespace NamespaceEncasement

{
  
    class Program
    {
        static void Main(string[] args)
        {
           //实例一个产品工厂类
            ProductFactory productFactory = new ProductFactory();
            //实例一个包装工厂
            WrapFactory wrapFactory = new WrapFactory();
            //委托了一个做Pizza的方法
            Func<Product> func1 = new Func<Product>(productFactory.MakePizza) ;
            //委托了一个做Toycar的方法
            Func<Product> func2 = new Func<Product>(productFactory.MakeToyCar);
            Box box1 = wrapFactory.WrapProduct(func1);//调用委托
            Box box2 = wrapFactory.WrapProduct(func2);
            Console.WriteLine(box1.product.Name);
            Console.WriteLine(box2.product.Name);
            Console.ReadKey();
        }
   


    }
    //声明一个产品类,只包含产品名属性
    class Product

    {
        public string Name { get; set; }
  //声明一个盒子类,包含产品属性
    }
    class Box
    {
        public Product product { get; set; }
    }
    /// <summary>
    /// 模板方法
    /// </summary>
    //包装工厂类
    class WrapFactory
    {   
        //制造盒子的方法
        public Box WrapProduct(Func<Product> getProduct)
        {
            //实例一个盒子
             Box box = new Box();
             //左边为产品类变量,右边为委托进来的方法执行
            Product product = getProduct.Invoke();
            box.product = product;
            return box;
        }
    }
    //产品加工厂类
    class ProductFactory
    {
    //创造披萨的方法
        public Product MakePizza()
        {
        //实例一个产品,产品名为pizza
        Product product = new Product();
        product.Name="Pizza";
            return product;
        }
       //创造车的方法
        public Product MakeToyCar()
        {
         //实例一个产品,产品名为车
            Product product = new Product();
            product.Name = "Toy Car";
            return product;
        }
    }

    }

回调方法

回调方法,通过委托类型参数传进主调方法,再调入被调方法(可以调用可以不调用,可以在需要的时候调用)。

using System;
using System.Collections.Generic;

using System.Windows.Forms;
namespace NamespaceEncasement

{
  
    class Program
    {
        static void Main(string[] args)
        {
            ProductFactory productFactory = new ProductFactory();
            WrapFactory wrapFactory = new WrapFactory();
            Func<Product> func1 = new Func<Product>(productFactory.MakePizza) ;
            Func<Product> func2 = new Func<Product>(productFactory.MakeToyCar);
            Logger logger = new Logger();
            Action<Product> log = new Action<Product>(logger.Log);
        
            Box box1 = wrapFactory.WrapProduct(func1,log);
            Box box2 = wrapFactory.WrapProduct(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} created at {1}.Price is  {2}", product.Name,DateTime.UtcNow,product.Price);
        }
    }
    class Product

    {
        public double  Price { get; set; }
        public string Name { get; set; }

    }
    class Box
    {
        public Product product { get; set; }
    }
    /// <summary>
    /// 模板方法
    /// </summary>
    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 MakeToyCar()
        {
            Product product = new Product();
            product.Name = "Toy Car";
            product.Price = 100;
            return product;
        }

    }

    }
  

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ci9IeVUr-1676261797957)(assets/image-20220614212649-pk81dvm.png)]

不管是回调方法还是模板方法,都是用委托类型的参数封装一个外部的方法,然后通过外部传进内部,再进行间接调用。

线程

接口替代委托

using System;
using System.Collections.Generic;

using System.Windows.Forms;
namespace NamespaceEncasement

{
  
    class Program
    {
        static void Main(string[] args)
        {
            IProductFactory pizzayFactory = new PizzaFactory();
            IProductFactory toyCatFactory = new ToyCarFacoty();
            WrapFactory wrapFactory = new WrapFactory();
  
    
            Box box1 = wrapFactory.WrapProduct(pizzayFactory);
            Box box2 = wrapFactory.WrapProduct(toyCatFactory);
            Console.WriteLine(box1.product.Name);
            Console.WriteLine(box2.product.Name);
            Console.ReadKey();
        }
   


    }
    class Logger
    {
        public void Log(Product product)
        {
            Console.WriteLine("Product{0} created at {1}.Price is  {2}", product.Name,DateTime.UtcNow,product.Price);
        }
    }
    interface IProductFactory
    {
        Product Make();
    }
    class PizzaFactory : IProductFactory
    {
        public Product Make()
        {
            Product product = new Product();
            product.Name = "Pizza";
            product.Price = 12;
            return product;
        }
  
    }
    class ToyCarFacoty : IProductFactory
    {
        public Product Make()
        {
            Product product = new Product();
            product.Name = "Toy Car";
            product.Price = 100;
            return product;
        }
    }

    class Product

    {
        public double Price { get; set; }
        public string Name { get; set; }

    }
    class Box
    {
        public Product product { get; set; }
    }
    /// <summary>
    /// 模板方法
    /// </summary>
    class WrapFactory
    {
        public Box WrapProduct(IProductFactory productFactory)
        {
            Box box = new Box();
            Product product = productFactory.Make();
   
            box.product = product;
            return box;
        }
    }
  
   
    }

    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值