威尼斯人线上娱乐

【威尼斯人线上娱乐】架构的血流,委托学习

31 3月 , 2019  

本篇小说重要介绍委托的选拔。

标签(空格分隔): C#


Delegate Predicate Action Func逆变和协变

寄托是豪门最广大的语法了,但会用与通晓之间的差别是伟人的。


 

  先说下什么样是委托(Delegate),委托在C#中是一连串型,和Class是二个级别,然则我们常常把它看成是多少个措施。为何是艺术?准确的说应该是回调函数,在C运维时的qsort函数获取指向3个回调函数的指针,以便对数组中的成分进行排序。C#中提供了一种体制,正是信托,一种回调函数的体制

二个程序员假若不可能了解委托,那么,他永世不可能变成高档程序员。

看马克down效果扶助的一点都不大好。

信托概述

将艺术调用者和对象措施动态关联起来,委托是三个类,所以它和类是同级的,能够由此信托来掉用艺术,不要误以为委托和章程同级的,方法只是类的成员。委托定义了法子的种类(定义委托和与之相应的法子必须怀有同等的参数个数,并且类型相同,重返值类型相同),使得能够将艺术当作另2个办法的参数来进展传递,那种将艺术动态地赋给参数的做法,可防止止在先后中山大学量行使If-Else(Switch)语句,同时使得程序有所更好的可扩张性。

 

  在大家做项指标进程中,委托用到的地点重重,像线程中期维修改窗体的景况、窗体控件事件和异步操作已成功等,在此之前我们创制委托的时候用delegate关键字,而且也比较费心,自从C#4.0有了泛型,也就有了泛型委托,使用Predicate、Action和Func大家得以更好的创办委托。

因而,让我们把委托刻到血液里吧。

买来《CLR Via
C#》这本书很久了,一贯也不曾对其进展计算,看的老大混乱,趁此机会好好计算一下,也算对C#读书的3个总结。

基本功委托(Delegate)

在.Net中扬言委托行使主要词delegate,委托具备多种选择方法(以下均为共同委托调用):

 1     /// <summary>
 2     /// 普通委托基础调用方式(同步委托)
 3     /// </summary>
 4     public class Delegates
 5     {
 6         /// <summary>
 7         /// 定义有参无返回值委托
 8         /// </summary>
 9         /// <param name="i"></param>
10         public delegate void NoReturnWithParameters(string o);
11         /// <summary>
12         /// 构造函数实例化
13         /// </summary>
14         public void DemoOne()
15         {
16             NoReturnWithParameters methord = new NoReturnWithParameters(this.Test);
17             methord.Invoke("One-ok");
18         }
19         /// <summary>
20         /// 赋值对象
21         /// </summary>
22         public void DemoTwo()
23         {
24             NoReturnWithParameters methord = this.Test;
25             methord.Invoke("Two-ok");
26         }
27         /// <summary>
28         /// DotNet 2.0 
29         /// </summary>
30         public void DemoThree()
31         {
32             NoReturnWithParameters methord = new NoReturnWithParameters(
33                 delegate (string o)
34                      {
35                          Console.WriteLine("有参无返回值:{0}", o);
36                      }
37             );
38             methord.Invoke("Three-ok");
39         }
40         /// <summary>
41         /// DotNet 3.0 
42         /// </summary>
43         public void DemoFour()
44         {
45             NoReturnWithParameters methord = new NoReturnWithParameters(
46                 (string o) =>
47                     {
48                         Console.WriteLine("有参无返回值:{0}", o);
49                     }
50             );
51             methord.Invoke("Four-ok");
52         }
53         /// <summary>
54         /// 委托约束
55         /// </summary>
56         public void DemoFive()
57         {
58             NoReturnWithParameters methord = new NoReturnWithParameters(
59                 (o) =>
60                 {
61                     Console.WriteLine("有参无返回值:{0}", o);
62                 }
63             );
64             methord.Invoke("Five-ok");
65         }
66         /// <summary>
67         /// 方法只有一行去则掉大括号及分号
68         /// </summary>
69         public void DemoSix()
70         {
71             NoReturnWithParameters methord = new NoReturnWithParameters((o) => Console.WriteLine("有参无返回值:{0}", o));
72             methord.Invoke("Six-ok");
73         }
74         public void DemoSeven()
75         {
76             NoReturnWithParameters methord = (o) => Console.WriteLine("有参无返回值:{0}", o);
77             methord.Invoke("Seven-ok");
78         }
79         /// <summary>
80         /// 定义有参无返回值测试方法
81         /// </summary>
82         /// <param name="o"></param>
83         private void Test(string o)
84         {
85             Console.WriteLine("有参无返回值:{0}", o);
86         }
87         /*
88          * 作者:Jonins
89          * 出处:http://www.cnblogs.com/jonins/
90          */
91     }

 

Delegate

  我们原先定义1个委托能够那样:

01.``1         delegate Boolean delgate1(``int
item);

02.`` ``2         public void
delgateCommon()

03.`` ``3         {

04.`` ``4             var d1 = ``new
delgate1(delegateMethod1);

05.`` ``5             if
(d1(``1``))

06.`` ``6             {

07.`` ``7

08.`` ``8             }

09.`` ``9         }

10.``10         static
bool delegateMethod1(``int item)

11.``11         {

12.``12             return
false``;

13.``13         }

  通过下面不难的以身作则能够见见,先创制四个delgate1的嘱托项目,参数类型是int,再次来到值时bool,下面定义3个静态方法delegateMethod1,成立3个delgate1类型的实例,参数为delegateMethod1方法名,那个也成为订阅或是注册,为那几个委托项目注册3个回调方法,下边正是调用了,大家在C#开创调用三个信托正是那般简单,其实是很复杂的,只可是这么些工作是编写翻译器帮大家做了。

  须要注意的是地点定义的回调方法是静态(static),借使大家创设的不是静态方法,也是足以,只可是调用的时候需求实例访问。

  静态方法都以通过首要字static来定义的,静态方法不必要实例那一个目的就足以经过类名来访问那一个目的。在静态方法中不可能直接待上访问类中的非静态成员。而用实例方法则须要通过切实的实例对象来调用,并且能够访问实例对象中的任何成员。借使用委托绑定实例方法的话必要用实例对象来走访,所以大家在绑定实例方法到委托的时
候必须同时让委托获得实例对象的音讯,那样才能在信托被回调的时候成功施行这一个实例方法。也正是说,当绑定实例方法给委托的时候,参数会被设置为这么些参数所在类型的实例对象。就算给委托绑定的是静态方法,那么那些参数将棉被服装置为NULL。

  综上,委托既能够绑定静态方法也足以绑定实例方法,可是在绑定实例方法的时候,delegate的target属性就被安装为指向那一个实例方法所属类别的三个实例对象。当绑定静态方法时,delegate的target属性就给NULL。

  废话说的有个别多,下边我们看下C#泛型委托,和重组一些匿名函数,lambda表明式的利用,其实正是部分不一样平日的寄托。

如此,你才能称之为[Developer]。

  • 初识委托
  • 用委托回调方法
  • 泛型委托
  • 简化语法

五头委托&异步委托

同步委托:委托的Invoke办法用来进行共同调用。同步调用也足以叫阻塞调用,它将堵塞当前线程,然后实施调用,调用达成后再持续向下进展。

异步委托:异步调用不封堵线程,而是把调用塞到线程池中,程序主线程或UI线程能够继续执行。委托的异步调用通过BeginInvokeEndInvoke来实现。

以下为异步委托调用格局:

 1     class Program
 2     {
 3         /// <summary>
 4         /// 定义有参无返回值委托
 5         /// </summary>
 6         /// <param name="i"></param>
 7         public delegate void NoReturnWithParameters(string o);
 8         static void Main(string[] args)
 9         {
10             NoReturnWithParameters methord = new NoReturnWithParameters(Test);
11             Console.WriteLine("主线程执行1");
12             Console.WriteLine("主线程执行2");
13             methord.BeginInvoke("demo-ok", null, null);
14             Console.WriteLine("主线程执行3");
15             Console.WriteLine("主线程执行4");
16             Console.ReadKey();
17         }
18         /// <summary>
19         /// 异步调用委托方法
20         /// </summary>
21         /// <param name="o"></param>
22         static void Test(string o)
23         {
24             Console.WriteLine("有参无返回值:{0}", o);
25         }
26         /*
27          * 作者:Jonins
28          * 出处:http://www.cnblogs.com/jonins/
29          */
30     }

因为调用BeginInvoke为异步委托,不会卡住主线程,运转结果如下:

威尼斯人线上娱乐 1

 

Predicate

 

01.``1     // 摘要:

02.`` ``2    
//     表示定义一组条件并确定指定对象是否符合这些条件的方法。

03.`` ``3     //

04.`` ``4     // 参数:

05.`` ``5     //   obj:

06.`` ``6    
//     要按照由此委托表示的方法中定义的条件进行比较的对象。

07.`` ``7     //

08.`` ``8     // 类型参数:

09.`` ``9     //   T:

10.``10    
//     要比较的对象的类型。

11.``11     //

12.``12     // 返回结果:

13.``13    
//     如果 obj 符合由此委托表示的方法中定义的条件,则为 true;否则为 false。

14.``14     public
delegate bool Predicate<in T>(T obj);

  能够见到Predicate的签署是3个泛型参数,再次来到值是bool。须求专注的是T前面包车型地铁in表示什么意思?请点这里。代码能够如此写:

 

01.``1         public void
delgatePredicate()

02.`` ``2         {

03.`` ``3威尼斯人线上娱乐 ,             var d1 = ``new
Predicate<``int``>(delegateMethod2);

04.`` ``4             if
(d1(``1``))

05.`` ``5             {

06.`` ``6

07.`` ``7             }

08.`` ``8         }

09.`` ``9         static
bool delegateMethod2(``int item)

10.``10         {

11.``11             return
false``;

12.``12         }

  能够见到采取Predicate创设委托简化了恒河沙数,大家能够自定义参数,可是只可以有二个,而且再次回到值必须是bool类型,是否感到限制太多了?无重临值或是五个参数怎么办?请看下边。

寄托的定义

初识委托

寄托类型 (delegate type)
表示对具有特定参数列表和返回类型的方法的引用(个人认为那句话对信托的诠释11分好)。通过信托,大家能够将艺术作为实体赋值给变量和作为参数字传送递。委托类似于在其它某个语言中的函数指针的定义。.NET Framework通过委托来提供回调函数机制,委托儿和保育管了回调函数是类型安全的。
调用贰个寄托的法门:

  1. 声圣元(Synutra)(Nutrilon)个信托项目
  2. 宣称3个措施包蕴要执行的代码
  3. 开创一个寄托实例
  4. 调用那么些委托实例

【威尼斯人线上娱乐】架构的血流,委托学习。异步回调(Callback)

异步回调通过安装回调函数,当调用甘休时会自动调用回调函数,能够在回调函数里触发EndInvoke,那样就释放掉了线程,能够制止程序一直占据贰个线程。

 1     class Program
 2     {
 3         /// <summary>
 4         /// 定义有参有返回值委托
 5         /// </summary>
 6         /// <param name="i"></param>
 7         public delegate string ReturnWithParameters(string o);
 8         static void Main(string[] args)
 9         {
10             ReturnWithParameters methord = new ReturnWithParameters(Test);
11             Console.WriteLine("主线程执行1");
12             Console.WriteLine("主线程执行2");
13             /*
14              BeginInvoke方法参数个数不确定, 最后两个参数含义固定,如果不使用的话,需要赋值null
15              委托的方法无参数,这种情况下BeginInvoke中只有两个参数。
16              此外,委托的方法有几个参数,BeginInvoke中从左开始,对应响应的参数。
17              1.倒数第二个参数:是有一个参数值无返回值的委托,它代表的含义为,该线程执行完毕后的回调。
18              2.倒数第一个参数:向即回调中传值,用AsyncState来接受。
19              3.其它参数:对应委托方法的参数。
20              */
21             IAsyncResult asyncResult = methord.BeginInvoke("demo-ok", new AsyncCallback(Callback), "AsycState:给回调函数的参数传递在此处出传值");
22             Console.WriteLine("主线程执行3");
23             Console.WriteLine("主线程执行4");
24             Console.ReadKey();
25         }
26         /// <summary>
27         /// 异步调用委托方法
28         /// </summary>
29         /// <param name="o"></param>
30         /// <returns></returns>
31         private static string Test(string o)
32         {
33             return "委托方法执行成功:" + o;
34         }
35         /// <summary>
36         /// 回调函数
37         /// </summary>
38         /// <param name="asyncResult"></param>
39         private static void Callback(IAsyncResult asyncResult)
40         {
41             /*
42              *asyncResult为回调前异步调用方法返回值
43              *AsyncResult 是IAsyncResult接口的一个实现类,引用空间:System.Runtime.Remoting.Messaging
44              *AsyncDelegate 属性可以强制转换为定义的委托类型
45              */
46             ReturnWithParameters methord = (ReturnWithParameters)((System.Runtime.Remoting.Messaging.AsyncResult)asyncResult).AsyncDelegate;
47             Console.WriteLine(methord.EndInvoke(asyncResult));
48             Console.WriteLine(asyncResult.AsyncState);
49         }
50         /*
51          * 作者:Jonins
52          * 出处:http://www.cnblogs.com/jonins/
53          */
54     }

实践结果如下:

威尼斯人线上娱乐 2

注意:

1.异步调用只好调用叁次EndInvoke,不然会报错。

2.假诺不回调函数中执行EndInvoke,请在异步调用后手动执行EndInvoke方法释放财富。

 

Action

 

01.``1     // 摘要:

02.`` ``2    
//     封装一个方法,该方法具有两个参数并且不返回值。

03.`` ``3     //

04.`` ``4     // 参数:

05.`` ``5     //   arg1:

06.`` ``6    
//     此委托封装的方法的第一个参数。

07.`` ``7     //

08.`` ``8     //   arg2:

09.`` ``9    
//     此委托封装的方法的第二个参数。

10.``10     //

11.``11     // 类型参数:

12.``12     //   T1:

13.``13    
//     此委托封装的方法的第一个参数类型。

14.``14     //

15.``15     //   T2:

16.``16    
//     此委托封装的方法的第二个参数类型。

17.``17    
[TypeForwardedFrom(``"System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089"``)]

18.``18     public delegate ``void
Action<in T1, in T2>(T1 arg1, T2 arg2);

  下面是Action多少个泛型参数的签字,最多帮衬十七个泛型参数,能够看到Action无重返值,创制代码如下:

 

01.``1         public void
delgateAction()

02.`` ``2         {

03.`` ``3             var d1 = ``new
Action<``int``>(delegateMethod3);

04.`` ``4             var d2 = ``new
Action<``int``, string>(delegateMethod4);

05.`` ``5             d1(``1``);

06.`` ``6            
d2(``1``, ``""``);

07.`` ``7         }

08.`` ``8         static void
delegateMethod3(``int item)

09.`` ``9         {

10.``10         }

11.``11         static void
delegateMethod4(``int item, string str)

12.``12         {

13.``13         }

  即使大家想创建的委托项目是有多个参数,而且必供给有重临值,我们如何做?请看下边。

如何是委托?

用委托回调方法

//1、声明一个委托实例
internal sealed class DelegateIntro {
    internal delegate void Feedback(Int32 value);
    private static void StaticDelegateDemo() {
          Console.WriteLine("----- Static Delegate Demo -----");
          //传递的为NUll,处理每个数据项都不调用回调方法
          Counter(1, 3, null);
          //3、创建静态的委托实例,用委托回调静态方法
          Counter(1, 3, new Feedback(DelegateIntro.FeedbackToConsole));
          Counter(1, 3, new Feedback(FeedbackToMsgBox)); // "Program." is optional
          Console.WriteLine();
       }

    private static void InstanceDelegateDemo() {
          Console.WriteLine("----- Instance Delegate Demo -----");
          //3、创建实例委托,用委托回调实例方法
          DelegateIntro di = new DelegateIntro();
          Counter(1, 3, new Feedback(di.FeedbackToFile));

          Console.WriteLine();
       }

    private static void Counter(Int32 from, Int32 to, Feedback fb)     {
          for (Int32 val = from; val <= to; val++) {
             // If any callbacks are specified, call them
             if (fb != null)
             //4、调用这个委托
                fb(val);
          }
       }
    //2、声明一个方法包含要执行的代码
    private static void FeedbackToConsole(Int32 value) {
          Console.WriteLine("Item=" + value);
       }
    //2、声明一个方法包含要执行的代码
    private static void FeedbackToMsgBox(Int32 value) {
          MessageBox.Show("Item=" + value);
       }

    private void FeedbackToFile(Int32 value) {
          StreamWriter sw = new StreamWriter("Status", true);
          sw.WriteLine("Item=" + value);
          sw.Close();
       }
}

信托对象是艺术的包装器(wrapper),是格局能经过包装器来直接回调。如上的FeedbackToConsoleFeedbackToMsgBox办法通过委托包装,通过Counter措施来直接回调。
这么些事例中的全数操作都是项目安全的。例如:在构造Feedback委托对象时,编写翻译器确认保障FeedbackToConsoleFeedbackToMsgBox方法的署名包容于Feedback委托类型定义的署名。具体的说,多个法子都要获得二个参数(2个int32),而且两岸都熬有一致的归来类型(Void),将FeedbackToConsole的概念改为上边那样
private static Boolean FeedbackToCOnsole(string value){
···
}
C#编写翻译器将不会编写翻译以上代码,并告知一下不当:

error CS0123:”FeedbackToConsole”的重载均与信托”Feedback”不般配

将艺术绑定到委托时,C#和CLCR-V都允许引用类型的协变性逆变性协变性是指方法能回到从委托的回到类型派生的三个门类。逆变性是指方法获得的参数能够是委托的参数类型的基类。
比如:

delegate object Mycallback(fileStream s);

一心能够组织该委托类型的叁个实例并绑定到拥有以下原型的艺术

String SomeMethod(Stream s);

在此处,SomeMethod的归来类型String派生自信托的回来类型(Object),那是协变性;SomeMethod的参数类型Stream是信托的参数类型FileStream的基类,那是逆变性
小心唯有引用类型才支撑协变性和逆变性。

异步委托线程等待 

1.【Delegate】.EndInvoke(推荐)

1   public delegate void NoReturnWithParameters(string o);
2   NoReturnWithParameters noReturnWithParameters = new NoReturnWithParameters(...);
3        ......
4   noReturnWithParameters.EndInvoke(asyncResult);

2.【IAsyncResult】.AsyncWaitHandle.WaitOne(可以定义等待时间,超越等待时间不连续守候向下举办)

1  IAsyncResult asyncResult = null;
2  asyncResult.AsyncWaitHandle.WaitOne(2000);//等待2000毫秒,超时不等待

3.【IAsyncResult】.IsCompleted(是IAsyncResult对象的多天性质,该值提示异步操作是否已到位。不引进)

1  IAsyncResult asyncResult = xxx.BeginInvoke(...);
2  while (!asyncResult.IsCompleted)
3  {
4      //正在等待中
5  }

 

Func

 

01.``1     // 摘要:

02.`` ``2    
//     封装一个具有两个参数并返回 TResult 参数指定的类型值的方法。

03.`` ``3     //

04.`` ``4     // 参数:

05.`` ``5     //   arg1:

06.`` ``6    
//     此委托封装的方法的第一个参数。

07.`` ``7     //

08.`` ``8     //   arg2:

09.`` ``9    
//     此委托封装的方法的第二个参数。

10.``10     //

11.``11     // 类型参数:

12.``12     //   T1:

13.``13    
//     此委托封装的方法的第一个参数类型。

14.``14     //

15.``15     //   T2:

16.``16    
//     此委托封装的方法的第二个参数类型。

17.``17     //

18.``18     //   TResult:

19.``19    
//     此委托封装的方法的返回值类型。

20.``20     //

21.``21     // 返回结果:

22.``22    
//     此委托封装的方法的返回值。

23.``23    
[TypeForwardedFrom(``"System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089"``)]

24.``24     public
delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);

  上面是Func四个参数,3个重临值的签字,和Action一样最多帮助十七个再次回到值,唯一的界别是Func接济自定义再次回到值类型,也足以看出T一 、T2前修饰符是in,TResult前的修饰符是out,这一个上边有证实。创立调用代码:

 

01.``1         public void
delgateFunc()

02.`` ``2         {

03.`` ``3            
string hiddenMethodString = ``""``;

04.`` ``4             var d1 = ``new
Func<``int``, bool>(delegateMethod5);

05.`` ``5             var d2 = ``new
Func<``int``, string, string>(delegate(``int
item, string str)

06.`` ``6                 {

07.`` ``7                     return
hiddenMethodString;``//匿名方法,好处:可读性更好,可以访问当前上下文

08.`` ``8                 });

09.`` ``9             var d3 = ``new
Func<string, string>((a) => {

10.``10                 return
a;``//lambda表达式,a作为参数,自动判断类型,如果单条语句,省略{}

11.``11             });

12.``12             d1(``1``);

13.``13            
d2(``1``, ``""``);

14.``14             d3(``""``);

15.``15         }

16.``16         static
bool delegateMethod5(``int item)

17.``17         {

18.``18             return
true``;

19.``19         }

  上边包车型地铁代码中大家运用和匿名方式和lambda表明式,能够看来在那之中的补益,省略创立方法的经过,代码更简明,在Func中采取lambda表达式是很普遍的,匿名格局有个好处正是能够访问上下文中的变量,比如hiddenMethodString,关于匿名情势和lambda表明式在那就不做解读了,其实正是一种语法规范,随着C#的升华,也不停在向上转移中。

  完整示例代码:

威尼斯人线上娱乐 3威尼斯人线上娱乐 4

 

01.``1 using System;

02.`` ``2
using System.Collections.Generic;

03.`` ``3 using System.Linq;

04.`` ``4 using System.Text;

05.`` ``5

06.`` ``6
namespace Predicate_Action_Func

07.`` ``7 {

08.`` ``8     class Program

09.`` ``9     {

10.``10         static void
Main(string[] args)

11.``11         {

12.``12            
delgateCommon();

13.``13         }

14.``14

15.``15         #region 常规委托

16.``16         delegate Boolean delgate1(``int
item);

17.``17         public void
delgateCommon()

18.``18         {

19.``19             var d1 = ``new
delgate1(delegateMethod1);

20.``20             if
(d1(``1``))

21.``21             {

22.``22                
Console.WriteLine(``"111"``);

23.``23             }

24.``24         }

25.``25         bool delegateMethod1(``int
item)

26.``26         {

27.``27             return
true``;

28.``28         }

29.``29         #endregion

30.``30

31.``31        
#region Predicate委托-自定义参数(参数只能一个)

32.``32         public void
delgatePredicate()

33.``33         {

34.``34             var d1 = ``new
Predicate<``int``>(delegateMethod2);

35.``35             if
(d1(``1``))

36.``36             {

37.``37

38.``38             }

39.``39         }

40.``40         static
bool delegateMethod2(``int item)

41.``41         {

42.``42             return
false``;

43.``43         }

44.``44         #endregion

45.``45

46.``46        
#region Action委托-自定义参数(参数为多个,多类型,但无返回值)

47.``47         public void
delgateAction()

48.``48         {

49.``49             var d1 = ``new
Action<``int``>(delegateMethod3);

50.``50             var d2 = ``new
Action<``int``, string>(delegateMethod4);

51.``51             d1(``1``);

52.``52            
d2(``1``, ``""``);

53.``53         }

54.``54         static void
delegateMethod3(``int item)

55.``55         {

56.``56         }

57.``57         static void
delegateMethod4(``int item, string str)

58.``58         {

59.``59         }

60.``60         #endregion

61.``61

62.``62        
#region Func委托-自定义参数(参数为多个,多类型,但有返回值)

63.``63         public void
delgateFunc()

64.``64         {

65.``65            
string hiddenMethodString = ``""``;

66.``66             var d1 = ``new
Func<``int``, bool>(delegateMethod5);

67.``67             var d2 = ``new
Func<``int``, string, string>(delegate(``int
item, string str)

68.``68                 {

69.``69                     return
hiddenMethodString;``//匿名方法,好处:可读性更好,可以访问当前上下文

70.``70                 });

71.``71             var d3 = ``new
Func<string, string>((a) => {

72.``72                 return
a;``//lambda表达式,a作为参数,自动判断类型,如果单条语句,省略{}

73.``73             });

74.``74             d1(``1``);

75.``75            
d2(``1``, ``""``);

76.``76             d3(``""``);

77.``77         }

78.``78         static
bool delegateMethod5(``int item)

79.``79         {

80.``80             return
true``;

81.``81         }

82.``82         #endregion

83.``83     }

84.``84 }

View Code

信托实际上是一种档次,是一种引用类型。

泛型委托

.NET Framework今后支撑泛型,如再次来到void可用下边泛型

public delegate void Action();
public delegate void Action(T obj);
public delegate void Action(T1 arg1,T2 arg2);
public delegate void Action(T1 arg1,T2 arg2,T3 arg3);

实则,.NET
Framework今后提供了1多少个Action寄托,它们从无参数到最多千克个参数,使用起来11分便利。借使急需再次回到值,可采纳Func函数。假如须要采取ref或out关键字以传引用的主意传送参数,就须求团结定义委托了。

放置委托(泛化委托)

 .Net Framework 提供多个帮助泛型的松开委托,分别是Action<>Func<>,在System命名空间中定义,结合lambda表明式,可以增进开发成效。

威尼斯人线上娱乐 5威尼斯人线上娱乐 6

运用方法如下:

 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             //使用Action声明委托
 6             Action<string> action = TestAction;
 7             action.Invoke("action-demo-ok");
 8             //使用Func声明委托
 9             Func<string, string> func = TestFunc;
10             string result = func.Invoke("func-demo-ok");
11             Console.WriteLine(result);
12             Console.ReadKey();
13         }
14         private static void TestAction(string o)
15         {
16             Console.WriteLine("TestAction方法执行成功:{0}", o);
17         }
18         private static string TestFunc(string o)
19         {
20             return "TestFunc方法执行成功:" + o;
21         }
22         /*
23          * 作者:Jonins
24          * 出处:http://www.cnblogs.com/jonins/
25          */
26     }

Action:无再次回到值的泛型委托,近来.NET Framework提供了1四个Action寄托,它们从无参数到最多15个参数。

public delegate void Action

Action

无重回值的泛型委托

Action<int,string>

传扬参数int、string,无重返值的寄托

Action<int,string,bool> 

流传参数int,string,bool,无重回值的嘱托

Action<bool,bool,bool,bool> 

盛传五个bool型参数,无重回值的委托

Action最少0个参数,最多15个参数,无重临值。

 

 

 

 

 

Func:有重临值的泛型委托,.NET
Framework提供了1八个Func函数,允许回调方法重临值。

public delegate TResult Func

Func<int> 

无参,再次来到值为int的嘱托

Func<int,string>

盛传参数int,重临值为string类型的寄托

Func<object,string,bool> 

流传参数为object, string 重临值为bool类型的信托

Func<T1,T2,,T3,int> 表示

盛传参数为T1,T2,,T3(类型)重临值为int类型的嘱托

Func最少0个参数,最多1陆个参数,遵照重返值泛型再次来到。必须有再次回到值,不可为void。

 

 

 

 

 

本质上ActionFunc都为delegate ,在System命名空间中定义(in和out用来标识变量)

威尼斯人线上娱乐 7

除了还有Predicate,它是固定再次回到值为bool类型的泛型委托。Action和Func丰硕使用那里不做牵线。

注意:

1.信托定义不要太多,微软仅在MSCorLib.dll中就有进47个委托项目,而且.NET
Framework将来协助泛型,所以大家只需多少个泛型委托(在System命名空间中定义)就能代表须求得到多达15个参数的点子。

2.如需取得十四个以上参数,就不可能不定义本身的寄托项目。所以建议尽量利用内置委托,而不是在代码中定义越多的委托项目,那样能够收缩代码中的类型数量,同时简化编码。

3.如需利用ref或out关键字以传引用的措施传递参数,就需求定义本人的寄托。

 

逆变和协变

微软用delegate关键字来声称委托,delegate与int,string,double等重要字一样。都是声称用的。

简化语法

松开委托(泛化委托)参数协变&逆变

协变(out):假定S是B的子类,倘诺X(S)允许引用转换到X(B),那么称X为协变类。(援救“子类”向“父类”转换)
逆变(in):假定S是B的子类,如若X(B)允许引用转换到X(X),那么称X为协变类。(协理“父类”向“子类”转换)

正如泛化接口,泛型委托同一支撑协变与逆变

1     public delegate void Action<in T>(T obj);
2    
3     public delegate TResult Func<out TResult>();

Action在System命名空间中定义辅助逆变(in)

1         Action<object> x =...;
2         
3         Action<string> y = x;    

Func在System命名空间中定义援助协变(out)

1         Func<string> x =...;
2             
3         Func<object> y = x; 

一旦要定义2个泛化委托项目,最佳依照如下准则:
1.将只用在重返值的类型参数标注为协变(out)
2.将只用在参数的品种参数标注为逆变(in)

如何是逆变性、协变性?

  我们这么创建和调用委托:

 

01.``1        
delegate object delgate1(FieldAccessException item);

02.`` ``2         public void
delgateCommon()

03.`` ``3         {

04.`` ``4             var d1 = ``new
delgate1(delegateMethod1);

05.`` ``5             Console.WriteLine(d1(``new
FieldAccessException()));

06.`` ``6         }

07.`` ``7         static
string delegateMethod1(Exception item)

08.`` ``8         {

09.`` ``9             return
"123"``;

10.``10         }

  能够看来有个别差别了,参数和重临类型不一样,delegateMethod1的参数类型(Exception)是寄托的参数类型(FieldAccessException)的基类,delegateMethod1的归来类型(String)派生自信托的回来类型(Object),这种就是逆变和协变,编写翻译和平运动转是可以的,也便是说是被允许的,逆变和协变只可以用来引用类型,不用用于值类型或void。

  逆变性:方法获得的参数能够是寄托的参数类型的基类。

泛型类型参数能够从基类型更改为此类的派生类型
用in关键字标记逆变格局的门类参数
那一个参数一般作输入参数,这几个在Predicate、Action中拥有体现

  协变性:方法能回到从委托的回到类型派生的2个门类。

泛型类型参数能够从派生类型变更为它的基类型

  • 用out关键字来标记协变格局的项目参数
  • 本条参数一般作为再次来到值,这几个在Func的TResult再次来到参数有所显示

      大概有点晕,只要记住逆变是指参数,协变是指再次回到值;逆变是指基类到派生类,协变是指派生类到基类。

    ### 怎么用逆变,协变?

      泛型委托Predicate、Action和Func都用到了逆变和协变,我们也得以不应用它们自定义一种泛型委托,如下:

    01.``1        
    delegate TResult MyDelegate<in T,out TResult>(T obj);

    02.`` ``2         public void
    delgateZidingyi()

    03.`` ``3         {

    04.`` ``4             var d1 = ``new
    MyDelegate<FieldAccessException, object>(delegateMethod6);

    05.`` ``5             d1(``new
    FieldAccessException());

    06.`` ``6         }

    07.`` ``7         static
    string delegateMethod6(Exception item)

    08.`` ``8         {

    09.`` ``9             return
    "123"``;

    10.``10         }

      其实上边定义的嘱托项目MyDelegate,也不必要创设那么麻烦,使用Func就可以了,也从中看到泛型委托Predicate、Action和Func只是微软方便大家创造委托提供的一种办法,大家一齐能够自定义,上边也作证了逆变和协变所起到的作用。

下边先看下声宋代码,那里评释了三个委托。

简化语法1:不要构造委托对象。

如:

ThreadPool.QueueUserWorkItem(SomeAsyncTask,5);

本来ThreadPool类的静态QueueUserWorkItem艺术期待七个WaitCallback委托对象的引用,但你以后径直能够传递多个办法符合waitCallback项目就足以了。但C#编写翻译器其实依然会转变waitcallback信托对象–只是语法简化了罢了。

委托的包容性

打探委托的兼容性,更易于在利用委托时使大家创设的代码具有多态性

1.类型的包容性:就算签名相似,委托类也互不兼容。

1 delegate void D1();
2 delegate void D2();
3 ...
4 D1 d1=Method1;
5 D2 d2=d1;//编译时错误
6 D2 d2=new D2(d1);//这是允许的

假诺委托实例执行同一的靶子措施,则觉得它们是等价的。

1 delegate void D();
2 ...
3 D1 d1=Method1;
4 D2 d2=Method1;
5 Console.WriteLine(d1==d2);//True

一旦多播委托遵照同等的一一应用相同的艺术责任委托它们是等价的。

2.参数的包容性:当调用多个方法时,能够给艺术的参数提供超越其钦定项目标变量。这是例行的多态行为。同样,委托也足以又抢先其目的措施参数类型的参数,即逆变。

 1     class Program
 2     {
 3         //委托接受string类型参数
 4         delegate void NoReturnWithParameters(string o);
 5         static void Main(string[] args)
 6         {
 7             NoReturnWithParameters noReturnWithParameters = new NoReturnWithParameters(Test);
 8             noReturnWithParameters("demo-ok");
 9             Console.ReadKey();
10         }
11         //目标方法接受object类型参数
12         static void Test(object o)
13         {
14             Console.WriteLine("返回值:{0}", o);
15         }
16     }

上述代码将参数string在调用目的措施时隐式向上转换为Object。

3.回去类型的包容性:即便调用2个方法,获得的归来值类型也许抢先请求的门类,那是健康多态行为。同样,信托的回来类型能够低于它的指标措施的回到值类型即协变**。**

 1     class Program
 2     {
 3         //委托返回object类型
 4         delegate object NoReturnWithParameters(string o);
 5         static void Main(string[] args)
 6         {
 7             NoReturnWithParameters noReturnWithParameters = new NoReturnWithParameters(Test);
 8             object o = noReturnWithParameters("demo-ok");
 9             Console.WriteLine(o);
10             Console.ReadKey();
11         }
12         //目标方法返回string类型
13         static string Test(string o)
14         {
15             return "返回值:" + o;
16         }
17     }

注意:规范事件情势的宏图主题时再其采纳公共基类伊芙ntArgs时采用逆变。例如,能够用四个不等的信托调用同1个格局,一个传递Mouse伊芙ntArgs,另一个传递Key伊夫ntArgs。

 

public delegate void TestDelegate(string message);
public delegate int TestDelegate(MyType m, long num);

简化语法2:不须要定义回调方法(lambda表明式)

近来代码中,回调方法名称SomeAsyncTask传给ThreadPool的QueueUserWorkItem方法。借使艺术较为简单能够一直写为:

ThreadPool.QueueUserWorkItem(obj=>Console.WriteLine(Obj),5);

编写翻译器在见到则个lambda表达式后会生成一个匿名格局。新的语言专业提议开发职员多多使用lambda表达式语法。
书本中的用委托回调多个主意没有下结论,个人觉得以后二个形式已经大半了,等精通的好了再去研讨调用四个艺术。
小说另各州址:

多播委托(+=&-=)

有着的嘱托的实例都有多播的效能,自定义委托和松手委托都有,可以由此+=-=给委托扩张和删掉分化的点子,当输入参数后,各种方法会按顺序进行迭代处理,并重返最后一个措施的总结结果。下面是大致模拟总括器的一段代码:

 1     class Program
 2     {
 3         public delegate int MulticastInstance(int inputA, int inputB);
 4         static void Main(string[] args)
 5         {
 6             MulticastInstance multicastInstance = Addition;
 7             multicastInstance += new MulticastInstance(Reduce);
 8             multicastInstance += new MulticastInstance(Multiply);
 9             int result = multicastInstance(10, 5);
10             Console.WriteLine("最后执行得到的结果为:{0}", result);
11             Console.ReadKey();
12         }
13         /// <summary>
14         /// 加法
15         /// </summary>
16         /// <param name="inputA"></param>
17         /// <param name="inputB"></param>
18         /// <returns></returns>
19         private static int Addition(int inputA, int inputB)
20         {
21             int result = inputA + inputB;
22             Console.WriteLine("Addition方法执行结果:{0}", result);
23             return result;
24         }
25         /// <summary>
26         /// 减法
27         /// </summary>
28         /// <param name="inputA"></param>
29         /// <param name="inputB"></param>
30         /// <returns></returns>
31         private static int Reduce(int inputA, int inputB)
32         {
33             int result = inputA - inputB;
34             Console.WriteLine("Reduce方法执行结果:{0}", result);
35             return result;
36         }
37         /// <summary>
38         /// 乘法
39         /// </summary>
40         /// <param name="inputA"></param>
41         /// <param name="inputB"></param>
42         /// <returns></returns>
43         private static int Multiply(int inputA, int inputB)
44         {
45             int result = inputA * inputB;
46             Console.WriteLine("Multiply方法执行结果:{0}", result);
47             return result;
48         }
49         /*
50          * 作者:Jonins
51          * 出处:http://www.cnblogs.com/jonins/
52          */
53     }

得到的结果如下:

威尼斯人线上娱乐 8

多播委托本质是:委托是不可变的,由此调用+=或-=的真相是成立三个新的寄托实例,并把它赋值给已有变量。全数的委托项目都是从System.MulticastDelegate派生的,它又一而再自System.Delegate,c#将委托中运用的+、-、+=、-=都编写翻译成System.Delegate的静态CombineRemove方法。

 

delegate既然是首要字,和int,string一样,那么,为何delegate后又跟了3个void可能int呢?

信托模拟观看者

能用委托解决的标题,都得以用接口消除。但再上面包车型地铁情况中,委托也许是比接口更好的抉择:

1.接口内之定义一个主意

2.亟待多播能力

3.订阅者供给频仍贯彻接口

上面代码是寄托的旁观者方式,优点是解耦且符合开放封闭原则:

 1 public class MulticastDelegates
 2 {
 3     public delegate int MulticastInstance(int inputA, int inputB);
 4     /// <summary>
 5     /// 模拟观察者
 6     /// </summary>
 7     public void Demo()
 8     {
 9         Manager manager = new Manager();
10         manager.Attach(new MulticastInstance(Add));
11         manager.Attach(new MulticastInstance(Reduce));
12         manager.Attach(new MulticastInstance(Multiply));
13         manager.Execute(10, 5);
14     }
15     /// <summary>
16     /// Observer模式、又称呼发布订阅或监听模式
17     /// </summary>
18     public class Manager
19     {
20         private MulticastInstance Handler;
21 
22         /// <summary>
23         /// 附加观察者
24         /// </summary>
25         /// <param name="handler1"></param>
26         public void Attach(MulticastInstance handler1)
27         {
28             Handler += handler1;
29         }
30         /// <summary>
31         /// 分离观察者
32         /// </summary>
33         /// <param name="handler1"></param>
34         public void Detach(MulticastInstance handler1)
35         {
36             Handler -= handler1;
37         }
38         /// <summary>
39         /// 如果观察者数量大于0即执行播委托列表中的方法
40         /// </summary>
41         /// <param name="inputA"></param>
42         /// <param name="inputB"></param>
43         public void Execute(int inputA, int inputB)
44         {
45             if (Handler != null)
46                 if (Handler.GetInvocationList().Count() != 0)
47                     Handler(inputA, inputB);
48         }
49     }
50     private int Add(int inputA, int inputB)
51     {
52         int result = inputA + inputB;
53         Console.WriteLine("Add方法执行结果:{0}", result);
54         return result;
55     }
56     private int Reduce(int inputA, int inputB)
57     {
58         int result = inputA - inputB;
59         Console.WriteLine("Reduce方法执行结果:{0}", result);
60         return result;
61     }
62     private int Multiply(int inputA, int inputB)
63     {
64         int result = inputA * inputB;
65         Console.WriteLine("Multiply方法执行结果:{0}", result);
66         return result;
67     }
68 }

 

一经她们是同样地位的重中之重字,为何能够一起行使呢?

信托揭秘

寄托看似很简单采纳,通过delegate珍视词定义,用驾驭的new组织委托实例,熟习的方法调用回调函数,但事实上编译器和CL昂科威在暗中做了多量做事来隐藏其复杂性。

重复审视上面总结器的一段代码:

1     public delegate int MulticastInstance(int inputA, int inputB);

实质上通过反编写翻译可观望:

威尼斯人线上娱乐 9

编写翻译器相当于概念了2个完好无损的类(继承自System.MulticastDelegate,定义多个方法:构造函数、Invoke、BeginInvoke和EndInvoke):

 

 1      internal class MulticastInstance : System.MulticastDelegate//继承System.MulticastDelegate
 2         {
 3             //构造器
 4             public MulticastInstance(object @object, IntPtr method);
 5             //这个方法的原型和源代码指定的一样
 6             public virtual int Invoke(int inputA, int inputB);
 7             //实现回调方法和异步回调
 8             public virtual IAsyncResult BeginInvoke(int inputA, int inputB, AsyncCallback callback, object @object);
 9             public virtual int EndInvoke(IAsyncResult result);
10         }
11         /*
12          * 作者:Jonins
13          * 出处:http://www.cnblogs.com/jonins/
14          */

所有委托项目都派生自System.MulticastDelegate类,System.MulticastDelegate派生自System.Delegate,后者又派生自System.Object。历史由来造成有三个委托类。
创设的有所寄托项目豆汁MulticastDelegate作为基类,个别意况下仍会用到Delegate。Delegate类的四个静态方法CombineRemove的签字都提议要收获Delegate参数。由于成立的嘱托项目派生自MulticastDelegate,后者又派生自Delegate,所以委托项指标实例是足以传递给那三个方法的。

MulticastDelegate的四个关键非公共字段

字段 类型 说明
_target System.Object

当委托对象包装一个静态方法时,这个字段为null。当委托对象包装一个实例方法时,这个字段引用的是回调方法要操作的对象。

当委托对象包装一个实例方法时,这个字段引用的是回调方法要操作的对象。换言之

换言之,这个字段指出要传给实例方法的隐士参数的值。

_methodPtr System.IntPtr

一个内部的整数值,CLR用它标记要回调的方法。

_invocationList System.Object 该字段通常为null,构造委托链时它引用一个委托数组。

Delegate反编写翻译后可看出静态方法CombineRemove(委托的+、-、+=、-=编译后的精神):

 1     [Serializable, ClassInterface(ClassInterfaceType.AutoDual), ComVisible(true), __DynamicallyInvokable]
 2     public abstract class Delegate : ICloneable, ISerializable
 3     {
 4         [ComVisible(true), __DynamicallyInvokable]
 5         public static Delegate Combine(params Delegate[] delegates);
 6         [__DynamicallyInvokable]
 7         public static Delegate Combine(Delegate a, Delegate b);
 8         [SecuritySafeCritical, __DynamicallyInvokable]
 9         public static Delegate Remove(Delegate source, Delegate value);
10     }

 

很简短,大家把delegate前面包车型地铁 【void TestDelegate(string
message)】精晓为多少个变量,是否就清晰明了了一些。

 结语

贰只委托将阻塞当前线程,等待方法执行完成继续执行程序,也等于直接调用方法。异步委托是将艺术放入线程池中推行并不打断主线程。异步委托从根本上说并不是二十四线程技术(职务Task也一律),就算异步委托内部将艺术塞给线程池去实施也并无法算得开辟新线程执行办法,(线程池一定开辟新线程)那种说法并不胆战心惊。信托本质是将调用者和对象措施动态关联起来,那是唯恐是本人所掌握的寄托存在的最根本指标吗。

 

咱俩把delegate关键字理解为,是用来尤其来定义那种复杂的变量的。而这种复杂的变量可以蕴含3个重回值和任性数目任意档次的传遍参数。

参考文献

CLR via C#(第4版) Jeffrey Richter

C#高档编制程序(第⑩版) Christian Nagel

果壳中的C# C#5.0高雅指南 Joseph Albahari

……


 

有没有觉得,这一个复杂的变量越发像贰个函数的概念。

科学,官方概念,委托项目标宣示与措施签名相似。所以,这几个纷纷变量,的确,书写的章程便是与函数一样。

那就是说,为啥那个宣称方式如此怪异呢,是因为,大家用delegate定义的变量,只可以用函数赋值。赋值格局如下所示:

public delegate void TestDelegate(string message);
public delegate long TestDelegate2(int m, long num);
public static void Excute()
{
    TestDelegate2 td = Double; 
} 
static long Double(int m, long num)
{
    return m * num;
}

委托的宗旨使用

学会了赋值未来,小编开首利用委托。

信托的行使办法如下:

string result = td(51, 8);
Console.WriteLine(result);

此地大家会发现,委托的应用办法与函数调用一样。

是的,它们确实是一致的。因为委托是用函数来赋值的,所以调用情势相同也并不意外,不是吧。

换一种说法,便是信托封装了三个函数。

若果委托是包装的函数,并且它又是援引类型。那么委托第3种符合规律的行使就显流露来了。

那便是——引用类型的函数。

要是函数是援引类型,那么那几个函数只要没被内部存储器回收,就能够被调用。若是是public函数也许是public
static函数,那么它能超越的东西就越多了。

譬如能够跨类调用,跨程序集调用等等。而那种用法,正是信托的着力使用。

匿名委托的行使

匿名委托的官方介绍:在 2.0 从前的 C#
版本中,证明委托的绝无仅有格局是应用命名格局。 C# 2.0 引入匿名形式,在 C#
3.0 及更高版本中,拉姆da 表明式取代匿超级模特式作为编纂内联代码的首要选拔办法。

看不懂没提到,大家一一向读书应用。代码如下:

delegate string anonymousDelegate(int m, long num);
public static void Excute()
{
    anonymousDelegate ad = delegate (int m, long num) { return m.ToString() + num.ToString(); };//2.0时代的匿名委托
    anonymousDelegate ad2 = (m, num) => { return m.ToString() + num.ToString(); };//3.0以后匿名委托 
}

如代码所示,匿名委托是拉姆da表明式,不懂的同窗就当它是有稳定写法即可,不用讲怎样道理,只要记住并运用即可。

匿名委托即便减弱了一点代码,但依旧供给大家协调去注明委托。全数,还可以够再简写一点呢?

答案自然是,能够的。

Action与Func

Action与Func是微软为我们事先定义好了的,多个委托变量。在那之中Action是不带重返值的委托,Func是带再次回到值的嘱托。

能够说,Action与Func完全包含了,大家家常便饭行使所需的,全体的,委托变量。

也正是说,大家能够不要再去协调手动注解委托了。

下边来看最简单易行的Action与Func的定义:

Action a1 = () => { };
Func<int> f1 = () => { return 1; };//必须写 return 1;

Action与Func是泛型委托,各补助1八个入参变量。下边代码为3个入参的定义,多参数以此类推。

Action<int> a1 = (i) =>  { };
Func<string,int> f1 = (str) => {  return 1;//必须写 return 1; };

信托的线程应用

委托的线程应用是信托的第③种用法,分为线程使用委托,和信托的异步应用三种。

我们先看线程使用委托。如下代码所示,2个无入参匿名Action和三个无入参匿名Func。

Task taskAction = new Task(() => { });//无入参匿名Action
taskAction.Start(); 
Task<int> taskFunc = new Task<int>(() => { return 1; });//无入参匿名Func
taskFunc.Start();
int result= taskFunc.GetAwaiter().GetResult();//获取线程返回结果

大家能见到二种委托行使,代码都拾壹分简短。

上边大家再来看委托的异步应用。首先看最简便的异步调用。

Action action = new Action(() => { });
IAsyncResult result = action.BeginInvoke((iar) =>
{
}, null);

Func<int> func = new Func<int>(() => { return 1; });  
IAsyncResult resultfunc = func.BeginInvoke((iar) =>
{
    var res = func.EndInvoke(iar); 
}, null);

此地大家运用委托的BeginInvoke方法来拉开线程,实行异步调用。如下面代码所示,这里介绍了Action与Func的最基础的异步应用。

寄托,框架结构的血流

寄托是架设的血流,如若系统中并未委托,那代码将堆叠到一块,比大力胶粘的都牢牢。

就好比一碗汤面倒掉了具有的汤,只要它静放3个阵子,就会成为一坨面球,让你无法下嘴。

从而,委托是架设的血液,是框架的流利的内核。

那正是说委托到底是怎么流动的吧?

大家先从刚介绍过的委托的线程应用说起。


第①着力应用——随手线程:

作者们在做开发的时候,一定接触过父类。父类是为什么的啊?父类经常是用来编排公共性质和函数,方便子类调用的。

那大家的寄托的率先个着力应用,正是父类的国有函数,线程随手运维。怎样随手翻开呢?

先是,大家创立父类代码如下:

class BaseDelegateSyntax
{ 
    public void AsyncLoad(Action action)
    {

    }
    public void AsyncLoad(Action action, Action callback)
    {
        IAsyncResult result = action.BeginInvoke((iar) =>
        {
            callback();
        }, null);
    }
    public void AsyncLoad<T>(Action<T> action, T para, Action callback)
    {
        IAsyncResult result = action.BeginInvoke(para, (iar) =>
        {
            callback();
        }, null);
    }
    public void AsyncLoad<T, R>(Func<T, R> action, T para, Action<R> callback)
    {
        IAsyncResult result = action.BeginInvoke(para, (iar) =>
        {
            var res = action.EndInvoke(iar);
            callback(res);
        }, null);
    }
}

咱俩看看地点的代码,父类中添加了多个异步委托的调用函数,接下去,我们就足以在持续该类的子类中,随手翻开线程了。

子类代码如下:

class ChildDelegateSyntax : BaseDelegateSyntax
{
    public void Excute()
    {
        //开启异步方法
        base.AsyncLoad(() => { });

        //开启异步方法,并且在异步结束后,触发回调方法
        base.AsyncLoad(() => { },
            ()=> 
            {
                //我是回调方法
            });

        //开启异步有入参的方法,传递参数,并且在异步结束后,触发回调方法
        base.AsyncLoad<string>((s) => { },"Kiba518",
           () =>
           {
                //我是回调方法
           });

        //开启异步有入参的方法,传递字符串参数Kiba518,之后返回int型结果518,
        //并且在异步结束后,触发回调方法,回调函数中可以获得结果518
        base.AsyncLoad<string,int>((s) => {
            return 518;
        }, "Kiba518",
           (result) =>
           {
               //我是回调方法 result是返回值518
           });
    }
}

看了上边包车型客车父子类后,是还是不是感觉委托让我们眼花缭乱的线程世界变简洁了吗?


其次着力应用——穿越你的世界:

接下去,大家来看委托的第2种为主用法,穿越的行使。

其一动用,是最广大,也最常见的利用了。因为委托是引用类型,所以A类里定义的寄托,能够在被内部存款和储蓄器回收在此之前,被其余类调用。

咱俩平日会在各个论坛看到有人提问,A页面怎么样调用B页面包车型客车习性、方法、父页面获取子页面包车型客车性子、方法,大概子页面获取父页面包车型客车特性、方法。

实质上,只要定义好委托,并将委托正确的传递,就足以兑现穿越的调用了。

上边大家看下穿越应用的代码。

public class FirstDelegateSyntax
{
    public FirstDelegateSyntax()
    {
        Console.WriteLine(" First 开始 "  );
        SecondDelegateSyntax sds = new SecondDelegateSyntax(()=> {
            Console.WriteLine(" First传给Second委托被触发 ");
        });
        sds.Excute();
        Console.WriteLine(" First 结束 ");
    }
}

public class SecondDelegateSyntax
{
    public Action Action { get; set; }
    public SecondDelegateSyntax(Action _action)
    {
        Console.WriteLine(" Second的构造函数 ");
        Action = _action;
    }
    public void Excute()
    {
        Console.WriteLine(" Second的Excute被触发 ");
        Action();
    }
}

大家能够见见,我们传递的嘱托,穿越了本人所属的类。在SecondDelegateSyntax类中被触发了。

运营结果如下:

威尼斯人线上娱乐 10

其四主旨应用——回调函数:

世界上本没有回调函数,叫的人多了,也就有了。

请牢记,全数的回调函数,都以寄托的通过应用,全数的回调函数;都以委托的穿越应用;全体的回调函数,都以信托的通过应用。

重要的话要讲一次。

因为委托是援引类型,所以能够被[址传递]。函数是不得以被传送的。

当您传递函数的时候,其实是匿名传递了2个寄托的地方。

结语

寄托是大家最常用的语法,它将函数封装成引用类型的变量,供别的单位调用。

因为委托的特质是引用类型,所以决定了寄托是足以拓展址传递。相当于说,委托是时时刻刻于大家系统代码中的列车。

咱俩能够在轻轨上放很多众多事物,在急需的站点,叫停高铁,并将托运的事物搬下来使用。

因而,理论上,只要大家选用好委托,就足以大大方方精减冗余的代码。

但委托那种列车,是每一个程序员都能够定义的,假使3个档次中有十一个开发者,各类人都在概念委托,那么,就有恐怕出现定义了十二个一律的信托的动静,这样就出现了撞车的场合。

从而委托在选择的时候,尽量做到有序传递,即预先做好列车的行驶路线,让委托遵照路径运营。尽量不要定义能够被其它单位调用的公家委托。

若是急需国有委托,能够行使反射的法子来调用。

前面小编会继续写事件,音信,反射等语法,敬请期待。

C#语法——元组类型

C#语法——泛型的有余行使

C#语法——await与async的科学打开药方式


注:此文章为原创,欢迎转发,请在小说页面分明地点给出此文链接!
若你觉得这篇文章还不易,请点击下右下角的【推荐】,万分多谢!
一旦您觉得那篇作品对你抱有帮忙,那就无妨支付宝小小打赏一下啊。 

威尼斯人线上娱乐 11

 


相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图