浅谈 C#委托

看了《CLR via
C#C#,》的17章委托后,为温馨做一点浅显的下结论,也分享给急需的人。

.NET通过委托来提供一种回调函数机制,.NET委托提供了诸多效应,例如确认保证回调方法是种类安全的(CLCR-V主要目的)。委托好允许顺序调用八个方法(委托链),并且支持调用静态方法和实例方法。

信托的骨干语法就不多说了。

internal delegate void Feedback(int value);
public sealed class Program{
      publick static void Main(){


      }

      private static void DelegateDemo(){
            Counter(1,2,new Feedback(WriteToConsole));
            Program p=new Program p();
            Counter(1,2,new Feedback(WriteToMsgBox));

      }

      private static void Counter(int from, int to, Feedback fb){
             for(int i=from;i<to;i++){
                   if(fb!=null)
                     fb(i);
             }

      }

      private static void WriteToConsole(int val){
             Console.WriteLine(val);

      }

      private void WriteToMsgBox(int val){
               MessageBox.Show(val)
      }



}

和普通调用静态方法实例方法没分别,假设急需回调静态方法,那么className.FuncName();  
若是须要回调实例方法,那么Class_object.FuncName();

鉴于委托是系列安全的,它能够调用私用方法。

协变性和逆变性。

将多少个办法绑定到委托的时候,C#和CL大切诺基都同意引用类型的协变性和逆变性,注意是引用类型哦。

delegate Object MyCallback(FileStream s);

string SomeMethod(Stream s);      //引用类型允许协变性,Stream是符合逆变性

int SomeOtherMethod(Stream s);   //值类型不允许协变性

协变性是指方法能回去从委托的归来类型派生的贰个类型,无法用于void。逆变性是指方法得到的参数是寄托的参数类型的基类。

委托链

 

Delegate.Combine(FirstDelegateObj,SecondDelegateObj);

FirstDelegateObj+=SecondDelegateObj;  //语法糖效果,等同于上一行

 上边代码就是在构造委托链。

委托链的原理大约正是:维护MulticastDelegate类中的八个重点的非公共字段中的_invocationList.那一个字段维护了委托数组。

除此以外多个字段就是_target.当委托包装了一个静态方法时,那些字段为null.当委托对象包装了一个实例方法时,那一个字段引用的是回调方法要操作的靶子。

                       _methodPtr 
一个里面包车型地铁平头值,CL陆风X8用它标识要回调的艺术。

在无数时候,执行委托链的进度中或许境遇在那之中某些方法的鸿沟和非凡影响接下去的主意的履行。这几个时候,大家的消除办法是选择MulticastDelegate为我们提供的GetInvocationList方法,获取由委托引用组成的数组,

种种委托引用只想链中的一个信托对象。大家得以由此遍历来推行每1个寄托。

委托链执行后只会回到最终二个回调方法所重返的值、

上面给出MulticastDelegate中Invoke方法的伪代码完毕,那几个主意解释了信托的实践进程和法则。

public int Invoke(int value)

{

      int result;

      Delegate[] delegateSet= _invoctionList as Delegate[];

      if(delegateSet !=null)

      {

          //委托链

          foreach(Feedback d in delegateSet)

          {

               result=d(value);

          }

      }

       else

      {

             //在执行对象上调用这个回调方法

              result= _methodPtr.Invoke(_target,value);

             //以上代码接近实际代码,但实际上C#表示不出来。

      }

      return result;

}

 

相关文章