コード例 #1
0
        public void Show()
        {
            NoReturnNoPara method = new NoReturnNoPara(this.DoNothing);

            method.Invoke();
            IAsyncResult asyncResult = method.BeginInvoke(null, null);
        }
コード例 #2
0
        public void Show()
        {
            {
                //多播委托有啥用呢?一个委托实例包含多个方法,可以通过+=/-=去增加/移除方法,Invoke时可以按顺序执行全部动作

                //多播委托:任何一个委托都是多播委托类型的子类,可以通过+=去添加方法
                //+=  给委托的实例添加方法,会形成方法链,Invoke时,会按顺序执行系列方法
                Action method = this.DoNothing;
                method += this.DoNothing;
                method += DoNothingStatic;
                method += new Student().Study;
                method += Student.StudyAdvanced;
                //method.BeginInvoke(null, null);//启动线程来完成计算  会报错,多播委托实例不能异步
                foreach (Action item in method.GetInvocationList())
                {
                    item.Invoke();
                    item.BeginInvoke(null, null);
                }
                //method.Invoke();
                //-=  给委托的实例移除方法,从方法链的尾部开始匹配,遇到第一个完全吻合的,移除,且只移除一个,如果没有匹配,就啥事儿不发生
                method -= this.DoNothing;
                method -= DoNothingStatic;
                method -= new Student().Study;//去不掉  原因是不同的实例的相同方法,并不吻合
                method -= Student.StudyAdvanced;
                method.Invoke();
                //中间出现未捕获的异常,直接方法链结束了
            }

            //System.MulticastDelegate
            Student student = new Student()
            {
                Id   = 96,
                Name = "一生为你"
            };

            student.Study();
            {
                NoReturnNoPara method = new NoReturnNoPara(this.DoNothing);
                //2 委托的实例化  要求传递一个参数类型 返回值都跟委托一致的方法,
                method.Invoke();                //3委托实例的调用  参数和委托约束的一致
                this.DoNothing();               //效果跟直接调用方法一致
                method();                       //可以省略.Invoke
                method.BeginInvoke(null, null); //启动一个线程完成计算
                //method.EndInvoke(null);

                //委托就是一个类 为什么要用委托? 这个类的实例可以放入一个方法,实例Inovke时,就调用方法
                //说起来还是在执行方法,为啥要做成三个步骤? 唯一的差别,就是把方法放入了一个对象/变量
            }
            {
                //WithReturnWithPara method = new WithReturnWithPara(this.ParaReturn);//严格一致
                //method += this.ParaReturn;
                //method.Invoke(out int a, ref b);
            }
            {
                WithReturnNoPara method = new WithReturnNoPara(this.Get);
                int i = method.Invoke();

                int k = this.Get();
            }

            {
                //Action Func  .NetFramework3.0出现的
                //Action 系统提供  0到16个泛型参数  不带返回值  委托
                //Action action = new Action(this.DoNothing);
                Action       action0 = this.DoNothing;//是个语法糖,就是编译器帮我们添加上new Action
                Action <int> action1 = this.ShowInt;
                Action <int, string, DateTime, long, int, string, DateTime, long, int, string, DateTime, long, int, string, DateTime, long> action16 = null;

                //Func 系统提供  0到16个泛型参数  带泛型返回值  委托
                Func <int>         func0   = this.Get;
                int                iResult = func0.Invoke();
                Func <int, string> func1   = this.ToString;

                Func <int, string, DateTime, long, int, string, DateTime, long, int, string, DateTime, long, int, string, DateTime, long, string> func16 = null;
            }
            {
                Action         action0 = this.DoNothing;
                NoReturnNoPara method  = this.DoNothing;
                //为啥框架要提供这种委托呢?  框架提供这种封装,自然是希望大家都统一使用Action/Func
                this.DoAction(action0);
                //this.DoAction(method);
                //委托的本质是类,Action和NoReturnNoPara是不同的类,虽然实例化都可以传递相同的方法,但是没有父子关系,所以是不能替换的
                //就像Student和Teacher两个类,实例化都是传递id/name,但是二者不能替换的

                //更进一步,框架中出现过N多个委托,委托的签名是一致的,实例化完的对象缺不能通用
                //new Thread(new ParameterizedThreadStart()).Start();
                //ThreadPool.QueueUserWorkItem(new WaitCallback())
                //Task.Run(new Action<object>());
                //本身实例化的时候,参数都是一样的,都是id/name,但却是不同的类型,导致没法通用
                //Action和Func  框架预定义的,新的API一律基于这些委托来封装

                //因为.Net向前兼容,以前的版本去不掉了,保留着,这是历史包袱
                //此后,大家就不要再定义新的委托了,包括大家的作业
            }

            {
                //多种途径实例化  实例化的限制就是方法的参数列表&返回值类型必须和委托约束的一致
                {
                    Action method = this.DoNothing;
                }
                {
                    Action method = DoNothingStatic;
                }
                {
                    Action method = new Student().Study;
                }
                {
                    Action method = Student.StudyAdvanced;
                }
            }


            {
                Func <int> func = this.Get;
                func += this.Get2;
                func += this.Get3;
                int iResult = func.Invoke();
                //结果是3  以最后一个为准,前面的丢失了。。所以一般多播委托用的是不带返回值的
            }
        }
コード例 #3
0
        public void Show()
        {
            Student student = new Student()
            {
                Id      = 123,
                Name    = "Ivan",
                Age     = 32,
                ClassId = 1
            };

            student.Study();

            {
                //把方法包装成变量, invoke 的时候自动执行方法
                NoReturnNoPara method = new NoReturnNoPara(this.DoNothing); // 2. 委托的实例化, 要求传入参数,参数为一个函数,函数必须与委托有同样的函数签名及返回值

                {
                    //3. 委托实例的调用, 相当于把传入的函数执行一遍
                    method.Invoke(); // Invoke 是delegate IL 中的方法, 相当于调用类的实例方法
                    method();        // 也可以直接省略Invoke进行调用
                }
            }

            {
                // beginInvoke
                WithReturnNoPara method = new WithReturnNoPara(this.GetSomething);
                int iResult             = method.Invoke();
                iResult = method();

                var result = method.BeginInvoke(null, null);// 异步调用
                method.EndInvoke(result);
            }
            {
                // 多途径实例化

                {
                    NoReturnNoPara method = new NoReturnNoPara(this.DoNothing);
                }
                {
                    NoReturnNoPara method = new NoReturnNoPara(DoNothingStatic);
                }
                {
                    NoReturnNoPara method = new NoReturnNoPara(Student.StudyAdvanced);
                }
                {
                    NoReturnNoPara method = new NoReturnNoPara(new Student().Study);
                }
            }
            {
                // 多播委托: 一个变量保存多个方法,可以增减;Invoke时候可以按顺序执行
                // += 为委托实例按顺序增加方法,形成方法链, Invoke时,是按顺序依次执行
                NoReturnNoPara method = new NoReturnNoPara(this.DoNothing);
                method += new NoReturnNoPara(this.DoNothing);
                method += new NoReturnNoPara(DoNothingStatic);
                method += new NoReturnNoPara(Student.StudyAdvanced);
                method += new NoReturnNoPara(new Student().Study);// 不是同一个实例, 所以是不同的方法
                method += new NoReturnNoPara(student.Study);
                method.Invoke();


                method.BeginInvoke(null, null); // 多播委托不能异步

                foreach (NoReturnNoPara item in method.GetInvocationList())
                {
                    item.Invoke();
                }

                // -= 为委托实例移除方法, 从方法链的尾部开始匹配,
                // 遇到第一个完全吻合的,移除且移除一个,没有也不异常
                method -= new NoReturnNoPara(this.DoNothing);
                method -= new NoReturnNoPara(DoNothingStatic);
                method -= new NoReturnNoPara(Student.StudyAdvanced);
                method -= new NoReturnNoPara(new Student().Study);
                method -= new NoReturnNoPara(student.Study);

                method.Invoke();

                {
                    WithReturnNoPara method1 = new WithReturnNoPara(this.GetSomething);

                    method1 += new WithReturnNoPara(this.GetSomething2);
                    method1 += new WithReturnNoPara(this.GetSomething3);

                    int result = method1.Invoke(); //多播委托带返回值,结果以最后的为准
                    Console.WriteLine(result);
                }
            }
        }