c# in deep 之委托

时间:2024-11-11 09:34:50

  通俗来讲,委托就是吩咐别人去做某件事,但不知道他具体会怎么做。使用委托必须注意的一个问题是内存泄露问题:假如委托实例本身不能被回收,委托实例会阻止他的目标被作为垃圾回收。尤其是假如某“短命”的对象调用了一个“长命”的对象中的事件,并用其自身作为目标。“长命”对象间接容纳了对“短命”对象的引用,延长了“短命”对象的寿命。下面是一个只为委托而委托的例子:

delegate void StringProgressor(string input);          //声明委托类型
    class Person
    {
        string name;
        public Person(string name) { this.name = name; }
        public void Say(string message)              //声明兼容的实例方法
        {
            Console.WriteLine("{0} says {1}",name,message);
        }
    }
    class Background
    {
        public static void Note(string note)            //声明兼容的静态方法
        {
            Console.WriteLine("({0})",note);
        }
    }
    class Program
    {
        static void Main()
        {
            Person jon = new Person("Jon");
            Person tom = new Person("Tom");
            StringProgressor jonsVoice, tomsVoice, background;//创建三个委托实例
            jonsVoice = new StringProgressor(jon.Say);
            tomsVoice = new StringProgressor(tom.Say);
            background = new StringProgressor(Background.Note);

jonsVoice("Hello son.");               //隐式调用委托实例
            tomsVoice.Invoke("Hello Daddy");          //显式调用委托实例
            background("An airplane flies past");
            Console.ReadKey();
        }
    }

  委托的实质是间接完成某种操作,这样做增大了代码的复杂性,但提高了代码的灵活性。在真正使用时,委托实例实际上有一个操作列表与之关联,称为委托实例的调用列表。其中Combine(+=)和Remove(-=)负责添加和删除。在委托实例被调用时,所有操作都按顺序执行,如果其有一个非void的返回值,则Invoke的返回值是最后一个操作返回值,假如有一个操作抛出异常,则后面的操作都会被停止。