C#笔记⑤——委托

委托

委托(delegate)是函数指针的升级版
算法(方法)是内存中一组机器语言指令
是特殊的类型
自定义委托(delegate)

点击查看代码
    delegate double Cal(double x,double y);
    class Program
    {
        static void Main(string[] args)
        {
            Cal cal=new Cal(Add);
            double result=cal.Invoke(5.0,6.0);
            System.Console.WriteLine(result);
            Console.ReadLine();
        } 

        public static double Add(double a,double b)
        {
            return a+b;
        }
    }

Action与Func

一般我们声明委托时,会用Action类与Func
Func类一般用于模板方法

Func<形参类型,返回类型> x=new Func<形参类型,返回类型>(xx.yy);

Action类一般用于回调方法(callback),一般用于无返回值的方法

Action<形参类型> x=new Action<形参类型>(xx.yy);
ACtion x=new Action(xx.yy);

模板方法
    class Program
    {
        static void Main(string[] args)
        {
            WrapFactory wrapfactory1=new WrapFactory();
            FoodFactory foodFactory=new FoodFactory();
            Box box1=new Box();
            Box box2=new Box();
            Func<Product> fun1=new Func<Product>(foodFactory.MakePizaa);
            Func<Product> fun2=new Func<Product>(foodFactory.MakeTC);
            box1=wrapfactory1.wrapFactory(fun1);
            box2=wrapfactory1.wrapFactory(fun2);

            System.Console.WriteLine(box1.product.Name);
            System.Console.WriteLine(box2.product.Name);
            Console.ReadLine();
        } 
    }

    class Product
    {
        public string Name{get;set;}
    }

    class Box
    {
        public Product product { get; set; }
    }

    class WrapFactory
    {
        public Box wrapFactory(Func<Product> cproduct)
        {
            Box box=new Box();
            Product product=cproduct.Invoke();
            box.product=product;
            return box;
        }

    }

    class FoodFactory
    {
        public Product MakePizaa()
        {
            Product pizaa=new Product();
            pizaa.Name="Pizaa";
            return pizaa;
        }

        public Product MakeTC()
        {
            Product tc=new Product();
            tc.Name="tc";
            return tc;
        }

    }


回调方法
    class Program
    {
        static void Main(string[] args)
        {
            WrapFactory wrapfactory1=new WrapFactory();
            FoodFactory foodFactory=new FoodFactory();
            Box box1=new Box();
            Box box2=new Box();
            Func<Product> fun1=new Func<Product>(foodFactory.MakePizaa);
            Func<Product> fun2=new Func<Product>(foodFactory.MakeTC);

            Logger log=new Logger();
            Action<Product> action=new Action<Product>(log.Log);

            box1=wrapfactory1.wrapFactory(fun1,action);
            box2=wrapfactory1.wrapFactory(fun2,action);

            System.Console.WriteLine(box1.product.Name);
            System.Console.WriteLine(box2.product.Name);
            Console.ReadLine();
        } 
    }


    class Logger
    {
        public void Log(Product product)
        {
        System.Console.WriteLine("{0} product was producted in {1} ,pirce 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 wrapFactory(Func<Product> cproduct,Action<Product> logger)
        {
            Box box=new Box();
            Product product=cproduct.Invoke();
            if(product.Price>=30)
            {
                logger.Invoke(product);
            }
            box.product=product;
            return box;
        }

    }

    class FoodFactory
    {
        public Product MakePizaa()
        {
            Product pizaa=new Product();
            pizaa.Name="Pizaa";
            pizaa.Price=20;
            return pizaa;
        }

        public Product MakeTC()
        {
            Product tc=new Product();
            tc.Name="tc";
            tc.Price=50;
            return tc;
        }

    }

开启线程

using System.Threading;
多托、多播(一个委托封装多个委托)Action x +=Action y 执行顺序看封装的先后顺序
每个运行程序就是一个进程,一个进程有一个或者多个线程(只有一个线程为主线程,其余都为分支线程)

同步与异步
同步:你做完我再做,是串行、单线程
异步:同时进行,是并行、多线程
同步调用:同一线内
异步调用:多线程内,但当争夺同一资源时会有可能冲突。


直接调用函数(直接同步)
        static void Main(string[] args)
        {
            Student stu1=new Student(){ID=1,PenColor=ConsoleColor.Red};
            Student stu2=new Student(){ID=2,PenColor=ConsoleColor.Green};
            Student stu3=new Student(){ID=3,PenColor=ConsoleColor.Cyan};

            stu1.DoHomework();
            stu2.DoHomework();
            stu3.DoHomework();
            for(int i =0;i<5;i++)
            {
                Console.ForegroundColor=ConsoleColor.DarkYellow;
                System.Console.WriteLine("{0} later",i);
                Thread.Sleep(1000);
            }
            Console.ReadLine();
        } 
    }

    class Student
    {
        public int ID { get; set; }
        public ConsoleColor PenColor{get;set;}

        public void DoHomework()
        {
            for(int i=0;i<5;i++)
            {
                Console.ForegroundColor=this.PenColor;
                Console.WriteLine("{0}Stuendt do homework with {1} hour",this.ID,i);
                Thread.Sleep(1000);
            }
        }
    }

间接同步(委托单播、多播)
    class Program
    {
        static void Main(string[] args)
        {
            Student stu1=new Student(){ID=1,PenColor=ConsoleColor.Red};
            Student stu2=new Student(){ID=2,PenColor=ConsoleColor.Green};
            Student stu3=new Student(){ID=3,PenColor=ConsoleColor.Cyan};

             Action a=new Action(stu1.DoHomework);
             Action b=new Action(stu2.DoHomework);
             Action c=new Action(stu3.DoHomework);

            //单播委托
            // a.Invoke();
            // b.Invoke();
            // c.Invoke();

            //多播
            a+=b;
            a+=c;
            a.Invoke();



            for(int i =0;i<5;i++)
            {
                Console.ForegroundColor=ConsoleColor.DarkYellow;
                System.Console.WriteLine("{0} later",i);
                Thread.Sleep(1000);
            }
            Console.ReadLine();
        } 
    }

    class Student
    {
        public int ID { get; set; }
        public ConsoleColor PenColor{get;set;}

        public void DoHomework()
        {
            for(int i=0;i<5;i++)
            {
                Console.ForegroundColor=this.PenColor;
                Console.WriteLine("{0}Stuendt do homework with {1} hour",this.ID,i);
                Thread.Sleep(1000);
            }
        }
    }

隐式异步
    class Program
    {
        static void Main(string[] args)
        {
            Student stu1=new Student(){ID=1,PenColor=ConsoleColor.Red};
            Student stu2=new Student(){ID=2,PenColor=ConsoleColor.Green};
            Student stu3=new Student(){ID=3,PenColor=ConsoleColor.Cyan};

            Action a=new Action(stu1.DoHomework);
            Action b=new Action(stu2.DoHomework);
            Action c=new Action(stu3.DoHomework);

            //隐式异步
            a.BeginInvoke(null,null);
            b.BeginInvoke(null,null);
            c.BeginInvoke(null,null);
            
            for(int i =0;i<5;i++)
            {
                Console.ForegroundColor=ConsoleColor.DarkYellow;
                System.Console.WriteLine("{0} later",i);
                Thread.Sleep(1000);
            }
            Console.ReadLine();
        } 
    }

    class Student
    {
        public int ID { get; set; }
        public ConsoleColor PenColor{get;set;}

        public void DoHomework()
        {
            for(int i=0;i<5;i++)
            {
                Console.ForegroundColor=this.PenColor;
                Console.WriteLine("{0}Stuendt do homework with {1} hour",this.ID,i);
                Thread.Sleep(1000);
            }
        }
    }

显式异步
    class Program
    {
        static void Main(string[] args)
        {
            Student stu1=new Student(){ID=1,PenColor=ConsoleColor.Red};
            Student stu2=new Student(){ID=2,PenColor=ConsoleColor.Green};
            Student stu3=new Student(){ID=3,PenColor=ConsoleColor.Cyan};

            //Thread显式异步
            // Thread a=new Thread(stu1.DoHomework);
            // Thread b=new Thread(stu2.DoHomework);
            // Thread c=new Thread(stu3.DoHomework);

            //Task显式异步
            Task a=new Task(stu1.DoHomework);
            Task b=new Task(stu2.DoHomework);
            Task c=new Task(stu3.DoHomework);

            a.Start();
            b.Start();
            c.Start();
            
            for(int i =0;i<5;i++)
            {
                Console.ForegroundColor=ConsoleColor.DarkYellow;
                System.Console.WriteLine("{0} later",i);
                Thread.Sleep(1000);
            }
            Console.ReadLine();
        } 
    }

    class Student
    {
        public int ID { get; set; }
        public ConsoleColor PenColor{get;set;}

        public void DoHomework()
        {
            for(int i=0;i<5;i++)
            {
                Console.ForegroundColor=this.PenColor;
                Console.WriteLine("{0}Stuendt do homework with {1} hour",this.ID,i);
                Thread.Sleep(1000);
            }
        }
    }

接口替换委托案例

一般情况下,会用Interface代替委托,因为严重情况下委托会造成内存泄漏,委托属于一种紧耦合的方式,一当回调进里层,将会造成不可debug的后果。

点击查看代码
    class Program
    {
        static void Main(string[] args)
        {
            WrapFactory wrapfactory1=new WrapFactory();
            IProductFactor PizzaFactor=new Pizza();
            IProductFactor TcFactory=new Tc();
            Box box1=new Box();
            Box box2=new Box();

            Logger log=new Logger();
            Action<Product> action=new Action<Product>(log.Log);

            box1=wrapfactory1.wrapFactory(PizzaFactor,action);
            box2=wrapfactory1.wrapFactory(TcFactory,action);

            System.Console.WriteLine(box1.product.Name);
            System.Console.WriteLine(box2.product.Name);
            Console.ReadLine();

        } 
    }

    interface IProductFactor
    {
        Product Make();
        
    }

    class Pizza:IProductFactor
    {
        public Product Make()
        {
            Product pizaa=new Product();
            pizaa.Name="Pizaa";
            pizaa.Price=20;
            return pizaa;
        }
    }

    class Tc:IProductFactor
    {
        public Product Make()
        {
            Product tc=new Product();
            tc.Name="tc";
            tc.Price=50;
            return tc;
        }
    }

    class Logger
    {
        public void Log(Product product)
        {
        System.Console.WriteLine("{0} product was producted in {1} ,pirce 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 wrapFactory(IProductFactor cproduct,Action<Product> logger)
        {
            Box box=new Box();
            Product product=cproduct.Make();
            if(product.Price>=30)
            {
                logger.Invoke(product);
            }
            box.product=product;
            return box;
        }

    }

posted @ 2022-02-04 22:14  Ariaaaaa  阅读(10)  评论(0)    收藏  举报