clr via c# delegate

1,委托列子

internal delegate void Feedback(int value);
    class DelegateRef
    {
        public static void StaticDelegateDeomo()
        {
            Console.WriteLine("---------------static delegate Demo ------------");
            Counter(1, 3, null);
            Counter(1, 3, FeedBackToConsole);
            Counter(1, 3, FeedBackToMsgBox);
            Console.WriteLine();
        }
        public static void InstanceDelegateDemo()
        {
            Console.WriteLine("----------------Instance Delegate Demo ---------");
            DelegateRef p = new DelegateRef();
            Counter(1, 3, p.FeedBackToFile);
            Console.WriteLine();
        }
        public static void ChainDelegateDemo1(DelegateRef p)
        {
            Console.WriteLine("----------------Chain Delegate Demo ----------");
            Feedback chain = FeedBackToConsole;
            chain += FeedBackToMsgBox;
            chain += p.FeedBackToFile;
            Counter(1, 2, chain);
            Console.WriteLine();
            chain -= FeedBackToMsgBox;
            Counter(1, 2, chain);

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

        private static void FeedBackToConsole(int value)
        {
            Console.WriteLine("Item=" + value);
        }
        private static void FeedBackToMsgBox(int value)
        {
            MessageBox.Show("Item=" + value);
        }
        private void FeedBackToFile(int value)
        {
            using(StreamWriter sw=new StreamWriter("Status", true))
            {
                sw.WriteLine("Item=" + value);
            }
        }
        public static void CallDelegateDemo()
        {
            StaticDelegateDeomo();
            InstanceDelegateDemo();
            ChainDelegateDemo1(new DelegateRef());
        }
    }

2,委托揭秘

在 Conter之中,实际上 +=是创建了Delegate的实列,并且调用了Combine函数,触发调用了invoke函数,移除调用了,remove函数

.method public hidebysig static void  ChainDelegateDemo1(class ClrFromCSharp_2_2.LearnDelegate.DelegateRef p) cil managed
// SIG: 00 01 01 12 60
{
  // 方法在 RVA 0x2ad4 处开始
  // 代码大小       122 (0x7a)
  .maxstack  3
  .locals init ([0] class ClrFromCSharp_2_2.LearnDelegate.Feedback chain)
  IL_0000:  /* 00   |                  */ nop
  IL_0001:  /* 72   | (70)000207       */ ldstr      "----------------Chain Delegate Demo ----------"
  IL_0006:  /* 28   | (0A)00001C       */ call       void [mscorlib]System.Console::WriteLine(string)
  IL_000b:  /* 00   |                  */ nop
  IL_000c:  /* 14   |                  */ ldnull
  IL_000d:  /* FE06 | (06)000059       */ ldftn      void ClrFromCSharp_2_2.LearnDelegate.DelegateRef::FeedBackToConsole(int32)
  IL_0013:  /* 73   | (06)000051       */ newobj     instance void ClrFromCSharp_2_2.LearnDelegate.Feedback::.ctor(object,
                                                                                                                   native int)
  IL_0018:  /* 0A   |                  */ stloc.0
  IL_0019:  /* 06   |                  */ ldloc.0
  IL_001a:  /* 14   |                  */ ldnull
  IL_001b:  /* FE06 | (06)00005A       */ ldftn      void ClrFromCSharp_2_2.LearnDelegate.DelegateRef::FeedBackToMsgBox(int32)
  IL_0021:  /* 73   | (06)000051       */ newobj     instance void ClrFromCSharp_2_2.LearnDelegate.Feedback::.ctor(object,
                                                                                                                   native int)
  IL_0026:  /* 28   | (0A)00003C       */ call       class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate,
                                                                                                                        class [mscorlib]System.Delegate)
  IL_002b:  /* 74   | (02)000017       */ castclass  ClrFromCSharp_2_2.LearnDelegate.Feedback
  IL_0030:  /* 0A   |                  */ stloc.0
  IL_0031:  /* 06   |                  */ ldloc.0
  IL_0032:  /* 02   |                  */ ldarg.0
  IL_0033:  /* FE06 | (06)00005B       */ ldftn      instance void ClrFromCSharp_2_2.LearnDelegate.DelegateRef::FeedBackToFile(int32)
  IL_0039:  /* 73   | (06)000051       */ newobj     instance void ClrFromCSharp_2_2.LearnDelegate.Feedback::.ctor(object,
                                                                                                                   native int)
  IL_003e:  /* 28   | (0A)00003C       */ call       class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate,
                                                                                                                        class [mscorlib]System.Delegate)
  IL_0043:  /* 74   | (02)000017       */ castclass  ClrFromCSharp_2_2.LearnDelegate.Feedback
  IL_0048:  /* 0A   |                  */ stloc.0
  IL_0049:  /* 17   |                  */ ldc.i4.1
  IL_004a:  /* 18   |                  */ ldc.i4.2
  IL_004b:  /* 06   |                  */ ldloc.0
  IL_004c:  /* 28   | (06)000058       */ call       void ClrFromCSharp_2_2.LearnDelegate.DelegateRef::Counter(int32,
                                                                                                               int32,
                                                                                                               class ClrFromCSharp_2_2.LearnDelegate.Feedback)
  IL_0051:  /* 00   |                  */ nop
  IL_0052:  /* 28   | (0A)000049       */ call       void [mscorlib]System.Console::WriteLine()
  IL_0057:  /* 00   |                  */ nop
  IL_0058:  /* 06   |                  */ ldloc.0
  IL_0059:  /* 14   |                  */ ldnull
  IL_005a:  /* FE06 | (06)00005A       */ ldftn      void ClrFromCSharp_2_2.LearnDelegate.DelegateRef::FeedBackToMsgBox(int32)
  IL_0060:  /* 73   | (06)000051       */ newobj     instance void ClrFromCSharp_2_2.LearnDelegate.Feedback::.ctor(object,
                                                                                                                   native int)
  IL_0065:  /* 28   | (0A)00003F       */ call       class [mscorlib]System.Delegate [mscorlib]System.Delegate::Remove(class [mscorlib]System.Delegate,
                                                                                                                       class [mscorlib]System.Delegate)
  IL_006a:  /* 74   | (02)000017       */ castclass  ClrFromCSharp_2_2.LearnDelegate.Feedback
  IL_006f:  /* 0A   |                  */ stloc.0
  IL_0070:  /* 17   |                  */ ldc.i4.1
  IL_0071:  /* 18   |                  */ ldc.i4.2
  IL_0072:  /* 06   |                  */ ldloc.0
  IL_0073:  /* 28   | (06)000058       */ call       void ClrFromCSharp_2_2.LearnDelegate.DelegateRef::Counter(int32,
                                                                                                               int32,
                                                                                                               class ClrFromCSharp_2_2.LearnDelegate.Feedback)
  IL_0078:  /* 00   |                  */ nop
  IL_0079:  /* 2A   |                  */ ret
} // end of method DelegateRef::ChainDelegateDemo1
    }

3,利用GetInvocationList()的方式,显示调用每一个委托,这样可以显式的处理每个委托的返回值和异常,否则

  • 当出现异常的时候,链表里面的下面的委托不会执行
  • 当出现阻塞时候,链表里面的下面的委托不会执行

4,委托和反射

internal static class DelegateReflection {
    // Here are some different delegate definitions
    private delegate Object TwoInt32s(Int32 n1, Int32 n2);
    private delegate Object OneString(String s1);

    public static void Go(String[] args) {
      if (args.Length < 2) {
         String fileName = Path.GetFileNameWithoutExtension(Assembly.GetEntryAssembly().Location);//获取执行文件的名称,但是没用

         String usage =//提示用法
            @"Usage:" +
            "{0}{1} delType methodName [Arg1] [Arg2]" +
            "{0}   where delType must be TwoInt32s or OneString" +
            "{0}   if delType is TwoInt32s, methodName must be Add or Subtract" +
            "{0}   if delType is OneString, methodName must be NumChars or Reverse" +
            "{0}" +
            "{0}Examples:" +
            "{0}   {1}TwoInt32s Add 123 321" +
            "{0}   {1}TwoInt32s Subtract 123 321" +
            "{0}   {1}OneString NumChars \"Hello there\"" +
            "{0}   {1}OneString Reverse  \"Hello there\"";
         Console.WriteLine(usage, Environment.NewLine, "DelegateReflection+");
         return;
      }

        // Convert the delType argument to a delegate type

      Type delType = Type.GetType(args[0]);//1,利用string返回类型Type...注意:DelegateReflection+TwoInt32s才是其TYPE
        if (delType == null) {
         Console.WriteLine("Invalid delType argument: " + args[0]);
         return;
      }

      Delegate d;
      try {
         // Convert the Arg1 argument to a method//注意,在某个类里面获取某个方法..方法名是arg[1],Add
         MethodInfo mi = typeof(DelegateReflection).GetMethod(args[1], BindingFlags.NonPublic | BindingFlags.Static);//2,获取类中方法

         // Create a delegate object that wraps the static method
         d = Delegate.CreateDelegate(delType, mi);//3,利用该方法将类的静态方法--->传送至委托.
      }
      catch (ArgumentException) {
         Console.WriteLine("Invalid methodName argument: " + args[1]);
         return;
      }

      // Create an array that that will contain just the arguments
      // to pass to the method via the delegate object
      Object[] callbackArgs = new Object[args.Length - 2];

      if (d.GetType() == typeof(TwoInt32s)) {//类型比较
         try {
            // Convert the String arguments to Int32 arguments
            for (Int32 a = 2; a < args.Length; a++)
               callbackArgs[a - 2] = Int32.Parse(args[a]);
         }
         catch (FormatException) {
            Console.WriteLine("Parameters must be integers.");
            return;
         }
      }

      if (d.GetType() == typeof(OneString)) {
         // Just copy the String argument
         Array.Copy(args, 2, callbackArgs, 0, callbackArgs.Length);
      }

      try {
         // Invoke the delegate and show the result
         Object result = d.DynamicInvoke(callbackArgs);//4,调用委托,动态给与参数.参数是object[]---必须匹配.
         Console.WriteLine("Result = " + result);
      }
      catch (TargetParameterCountException) {
         Console.WriteLine("Incorrect number of parameters specified.");
      }
   }

   // This callback method takes 2 Int32 arguments
   private static Object Add(Int32 n1, Int32 n2) {
      return n1 + n2;
   }

   // This callback method takes 2 Int32 arguments
   private static Object Subtract(Int32 n1, Int32 n2) {
      return n1 - n2;
   }

   // This callback method takes 1 String argument
   private static Object NumChars(String s1) {
      return s1.Length;
   }

   // This callback method takes 1 String argument
   private static Object Reverse(String s1) {
      Char[] chars = s1.ToCharArray();
      Array.Reverse(chars);
      return new String(chars);
   }
}
  1. 新建委托TYPE
  2. 从类中查找静态方法
  3. 利用Delegate.CreateDelegate建立类中静态方法的委托.
  4. 利用d.DynamicInvoke(object[])来调用委托,其中参数是一个数组匹配原静态方法的参数.如果不一致会报参数不匹配错误.
  5. TargetParameterCountException

猜你喜欢

转载自www.cnblogs.com/frogkiller/p/12285259.html