C#委托

 一 使用委托

    //1.声明一个委托类型
    internal delegate void Feedback(int value);
    class Program
    {
        //2. 定义一个符合委托类型的方法
        private static void FeedbackToConsole(int x)
        { Console.WriteLine(x.ToString()); }
        static void Main(string[] args)
        {
            //3.构造委托实例
            Feedback fb = new Feedback(FeedbackToConsole);
            
            //4. 调用委托
            fb(2);
        }       
    }

二  委托做了什么

当我们声明一个委托类型的时候,编译器实际帮我们定义了一个继承自MulticastDelegate的类

    internal class Feedback : MulticastDelegate
    {
        //构造器
        public Feedback(Object o, IntPtr m);

        //这个方法和源代码指定的原型一样
        public virtual void Invoke(int value);

        //以下方法实现了对回调方法的异步回调
        public virtual IAsyncResult BeginInvoke(int value, 
            AsyncCallback callback, Object o);
        public virtual void EndInvoke(IAsyncResult result);
    }

MulticastDelegate的三个重要非公共字段

    • _target    System.Object    当委托对象包装一个静态方法时,这个字段为null;实例方法时,这个值为回调方法要操作的对象。
    • _methodPtr    System.IntPtr    一个内部整数值,CLR用它标识要回调的方法
    • _invocationList    System.Object    构造一个委托链时,引用一个委托数组

三 委托链

四 泛型委托

  一般情况下我们不需要自己定义委托类型,.NET Framework为我们定义了两类泛型委托,分别是 Action和Func。每一类都有0-16个泛型参数的版本。Action无返回值,Func有返回值。

五 那些让人迷惑的简化语法

  1. 不需要构造委托对象。

  我们经常看到这样的写法:

      button1.Click += button1_Click; (button1_Click是方法名)

  这是一种简化的写法,完整的写法:

      button1.Click += new EventHandler(button1_Click);

  在前面使用委托的第三步我们也可以这样写:Feedback fb = FeedbackToConsole;

  2. 不需要定义回调方法。

   很多时候我们创建的回调方法只会使用一次,C#允许我们以内联的方式写回调方法的代码。例如我们可以把使用委托中的第二步省略,第三步改写为:

        Feedback fb = x => Console.WriteLine(x.ToString());

  “=>”是Lambda表达式操作符,“=”号右边的部分是一个Lambda表达式。编译器看到Lambda表达式后会自动定义一个新的私有方法,这个新方法称为匿名函数,因为方法的名称是编译器自动创建的。

  3. 局部变量不需要手动包装到类中即可传给回调方

posted @ 2013-03-21 16:39  hechaner  Views(145)  Comments(0)    收藏  举报