C#浅谈 C#委托

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

.NET通过信托来提供1种回调函数机制,.NET委托提供了不少作用,例如确定保障回调方法是连串安全的(CLOdyssey紧要目的)。委托好允许顺序调用七个格局(委托链),并且扶助调用静态方法和实例方法。

信托的中坚语法就不多说了。

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();

由于委托是项目安全的,它能够调用私用方法。

协变性和逆变性。

将1个措施绑定到委托的时候,C#和CLEscort都同意引用类型的协变性和逆变性,注意是援引类型哦。

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.当委托对象包装了1个实例方法时,这几个字段引用的是回调方法要操作的指标。

                       _methodPtr 
三个内部的平头值,CL奥德赛用它标识要回调的艺术。

在诸多时候,执行委托链的进程中或许蒙受在那之中某些方法的堵塞和非常影响接下去的秘籍的执行。今年,我们的消除办法是运用MulticastDelegate为大家提供的GetInvocationList方法,获取由委托引用组成的数组,

种种委托引用只想链中的2个委托对象。我们得以由此遍历来推行每3个信托。

C#,委托链执行后只会重临最终一个回调方法所再次来到的值、

上面给出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;

}

 

相关文章