019 委托

● 委托(delegate)是函数指针的“升级版”
○ 示例:C/C++ 中的函数指针
● 一切皆地址
○ 变量(数据)是以某个地址为起点的一段内存中所存储的值
○ 函数(算法)是以某个地址为起点的一段内存中所存储的一组机器语言指令
● 直接调用与间接调用
○ 直接调用:通过函数名来调用函数,CPU 通过函数名直接获得函数所在地址并开始执行 -> 返回
○ 间接调用:通过函数指针来调用函数,CPU 通过读取函数指针存储的值获得函数所在地址并开始执行 -> 返回
● Java 中没有与委托相对应的功能实体
● 委托的简单使用
○ Action 委托
○ Func 委托

class Demo_Delegate
    {
        public void test()
        {
            Demo19_Calculator demo19_Calculator = new Demo19_Calculator();
            Action action = new Action(demo19_Calculator.Report);
            action.Invoke();
            action();

            Func<int,int,int> func = new Func<int, int, int>(demo19_Calculator.Add);
            Console.WriteLine(func(1, 1));
        }
    }

    class Demo19_Calculator
    {
        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;
        }

    }

使用delegate时:
根据delegate声明位置其生效范围也不相同
所以放在命名空间的最高层更好一些(?)

Func_Double multi = demo19_Calculator.Mul;
Console.WriteLine(multi(3, 3));
Func_Double devide = new Func_Double(demo19_Calculator.Div);//这样更有可读性??
Console.WriteLine();

委托的一般使用
在这里插入图片描述
模板方法:感觉有点类似于C++中STL的一些使用方法
回调方法:安卓全是这种

模板方法:
执行过程

WrapFactory wrapFactory = new WrapFactory();
ProductFactory productFactory = new ProductFactory();
Box box1 = wrapFactory.WrapProduct(productFactory.Produce, "apple");
Box box2 = wrapFactory.WrapProduct(productFactory.Produce, "banana");

相关类的实现

    class WrapFactory
    {
        public Box WrapProduct(Func<string,Product> getProduct,string productName)
        {
            Box box = new Box();
            box.product = getProduct.Invoke(productName);
            return box;
        }
    }
    class ProductFactory
    {
        public Product Produce(string productName)
        {
            Console.WriteLine("made a "+productName); 
            return new Product() { name = productName };
        }
    }

回调方法:

    class WrapFactory
    {
        public Box WrapProduct(Func<string,Product> getProduct,string productName ,Action<Product> logCallBack)
        {
            Box box = new Box();
            box.product = getProduct.Invoke(productName);
            if(box.product.price > 30)
            {
                logCallBack(box.product);
            }
            return box;
        }
    }
    class ProductFactory
    {
        public Product Produce(string productName)
        {
            Console.WriteLine("made a "+productName); 
            return new Product() { name = productName,price = productName[0]-' ' };
        }
    }

    class Logger
    {
        public static void Log(Product product)
        {
            Console.WriteLine("Product {0} created at {1}.Price is {2}", product.name, DateTime.Now, product.price);
        }
    }

本质上就是多用了一个委托类型的参数用于存储回调函数供使用
委托的高级使用:
在这里插入图片描述
示例:

class Demo_MultiCast
    {
        public void test()
        {
            Demo19_Student student1 = new Demo19_Student() { ID = 1, PenColor = ConsoleColor.Red };
            Demo19_Student student2 = new Demo19_Student() { ID = 2, PenColor = ConsoleColor.Green };
            Demo19_Student student3 = new Demo19_Student() { ID = 3, PenColor = ConsoleColor.Blue };
            Action action1 = student1.DoHomeWork;
            Action action2 = student2.DoHomeWork;
            Action action3 = student3.DoHomeWork;

            //action1 += action2;
            //action1 += action3;
            //action1();//同步调用

            //action1.BeginInvoke(null, null);//隐式异步
            //action2.BeginInvoke(null, null);
            //action3.BeginInvoke(null, null);//因为争抢ForegroundColor导致资源冲突,未能使得颜色一定对应于学生的PenColor

            //Thread thread1 = new Thread(new ThreadStart(student1.DoHomeWork));//显式异步调用
            //Thread thread2 = new Thread(new ThreadStart(student2.DoHomeWork));
            //Thread thread3 = new Thread(new ThreadStart(student3.DoHomeWork));

            //thread1.Start();
            //thread2.Start();
            //thread3.Start();

            //Task task1 = new Task(student1.DoHomeWork);//显式异步调用
            //Task task2 = new Task(student2.DoHomeWork);
            //Task task3 = new Task(student3.DoHomeWork);

            //task1.Start();
            //task2.Start();
            //task3.Start();

            Console.ForegroundColor = ConsoleColor.White;
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("Main Thread {0}",i);
                Thread.Sleep(500);
            }
        }
    }
    class Demo19_Student
    {
        public int ID { get; set; }
        public ConsoleColor PenColor { get; set; }
        public void DoHomeWork()
        {
            for(int i = 0; i < 5; i++)
            {
                Console.ForegroundColor = PenColor;
                Console.WriteLine("Student {0} is doing homework for {1} hours", ID, i);
                Thread.Sleep(500);
            }
        }
    }

写代码就完事了
接口的简单示范:
自己对比委托和接口的使用方法的具体差异

class WrapFactory
    {
        public Box WrapProduct(Func<string,Product> getProduct,string productName ,Action<Product> logCallBack)
        {
            Box box = new Box();
            box.product = getProduct.Invoke(productName);
            if(box.product.price > 30)
            {
                logCallBack(box.product);
            }
            return box;
        }

        public Box WrapProduct(IProductFactory productFactory, string productName, Action<Product> logCallBack)
        {
            Box box = new Box();
            box.product = productFactory.Make(productName);
            if (box.product.price > 30)
            {
                logCallBack(box.product);
            }
            return box;
        }
    }
    class ProductFactory:IProductFactory
    {
        public Product Produce(string productName)
        {
            Console.WriteLine("made a " + productName); 
            return new Product() { name = productName,price = productName[0]-' ' };
        }

        public Product Make(string productName)
        {
            return new Product() { name = productName, price = productName[0] - ' ' };
        }
    }

具体使用时(品)

Box box1 = wrapFactory.WrapProduct(productFactory.Produce, "apple", Logger.Log);
Box box2 = wrapFactory.WrapProduct(productFactory, "banana", Logger.Log);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值