C# 委托学习

定义
  委托是一种在对象里保存方法引用的类型,同时也是一种类型安全的函数指针;
  理解委托的一种方式可以把委托的作用当作是给方法签名指定名称;
  委托的定义类似于方法的定义,但没有方法体,定义的委托名前要加上关键字delegate;

因为定义委托基本上是定义一个新类,所以可以在定义类的任何地方定义委托,既可以在另一个类的内部定义委托,也可以在所有类的外部定义委托,还可以在命名空间中把委托定义为顶层对象。

根据定义的可见性,可以在委托定义上添加一般的访问修饰符:public、private和protected等。

一个委托实例压缩(或者称为封装)了一个方法称之为“一个可调用的实体” ,所以“一个可调用的实体”也就由这个委托实例本身和实例中封装的方法组成。

委托也可以包含多个方法,这种委托称为多播委托。

如果调用多播委托,就可以按顺序连续调用多个方法。为此,委托的签名就必须返回 void (否则,返回值应送到何处?)(当委托只包含一个方法的时候,其返回类型的声明可以参照所封装的方法,不一定必须是void)。实际上,如果编译器发现某个委托返回 void ,就会自动假定这是一个多播委托。

委托的优点:
  压缩方法的调用;
  合理有效地使用委托能提升应用程序的性能;
  用于调用匿名方法;
 
委托的声明:
  作用域修饰符 delegate 委托返回类型 委托名();
  如:public delegate  Void Test();
 
注意点:
  可以在不带参数或参数列表的情况下声明委托;
  应当遵循和声明方法一样的语法来声明委托;
 

如果调用多播委托,就可以按顺序连续调用多个方法。为此,委托的签名就必须返回 void (否则,返回值应送到何处?)(当委托只包含一个方法的时候,其返回类型的声明可以参照所封装的方法,不一定必须是void)。实际上,如果编译器发现某个委托返回 void ,就会自动假定这是一个多播委托。

以上文字摘自:http://www.cnblogs.com/huashanlin/archive/2008/03/11/1100870.html 


 

以下我自学时所作的例子,留在这里已被将来复习。

声明两个类,来进行实践: MySing.cs ReadBook.cs

 public class MySing
    {
        public void Sing(string Name, string Song, dSing sing)
        {
            sing(Name, Song);
        }
        public void OneSing(string Name, string Song)
        {
            Console.Write(string.Format("{0}唱了一首《{1}》。\n", Name, Song));
        }
        public void TwoSing(string Name, string Song)
        {
            Console.Write(string.Format("{0} singed the song {1}。\n", Name, Song));
        }
    }

    public class ReadBook
    {
        public string ReadIt(int Count, dReadBook drb)
        {
            return drb(Count);
        }
        public string ReadOne(int Count)
        {
            return string.Format("I readed {0} books Yestoday.\n", Count);
        }
        public string ReadTwo(int Count)
        {
            return string.Format("I readed {0} books Today.\n", Count);
        }
    }

 

 

主程序:

 public delegate void dSing(string Name, string Song);

 public delegate string dReadBook(int Count);
class Program { static void Main(string[] args) { MySing ms = new MySing(); Console.Write("-----------------普通委托-------------------------\n"); ms.Sing("小白", "亲密爱人", ms.OneSing);  //小白唱了一首《亲密爱人》。 ms.Sing("xb", "Love it", ms.TwoSing);   //xb singed the song Love it. dSing ds1, ds2; ds1 = ms.OneSing; ds2 = ms.TwoSing; ms.Sing("小白A", "亲密爱人A", ds1);     //小白A 唱了一首《亲密爱人A》。 ms.Sing("xbB", "Love it B", ds2);     //xbA singed the song Love it B. Console.Write("--------------------匿名委托--------------------\n"); dSing ds3 = delegate(string Name, string Song) { Console.Write(string.Format("{0}唱了一首《{1}》。\n", Name, Song)); }; ms.Sing("匿名", "匿名歌曲", ds3);      //匿名唱了一首《匿名歌曲》 Console.Write("-----------------多播委托---------------------\n"); ds1 = ds1 + ds2; ms.Sing("小白A", "亲密爱人A", ds1);     //小白A 唱了一首《亲密爱人A》。 and 小白A singed the song 亲密爱人A. 先调用ds1 再调用 ds2 ds2 = ds1 - ds2; ms.Sing("小白A", "亲密爱人A", ds2);     //小白A 唱了一首《亲密爱人A》。 实际上调用了之前的ds1 ds1 = ds1 - ds2; ms.Sing("小白A", "亲密爱人A", ds1);     //小白A singed the song 亲密爱人A. Console.Write("-----------------ReadBook 普通 delegate-------------------\n"); ReadBook rb = new ReadBook(); Console.Write(rb.ReadIt(10, rb.ReadOne)); Console.Write(rb.ReadIt(20, rb.ReadTwo)); Console.Write("-----------------ReadBook 多播 delegate--------------------\n"); dReadBook drb1, drb2; drb1 = rb.ReadOne; drb2 = rb.ReadTwo; Console.Write(rb.ReadIt(10, drb1));                   drb1 = drb1 + drb2; Console.Write(rb.ReadIt(10, drb1));   //由于这里的委托的函数返回值为void,所以多播委托失效,只能返回第一个委托的函数 I readed 10 books Today.   


            Console.Write("------------ReadBook 匿名 delegate------------------\n");
            dReadBook drb3 = delegate(int Count)
            {
                return string.Format("I readed {0} books sometimes.\n", Count);
            };

            Console.Write(rb.ReadIt(121, drb3));

        }

 

 

posted @ 2014-04-12 23:00  蓝天_野菜  阅读(194)  评论(0)    收藏  举报