C# 委托学习
定义:
委托是一种在对象里保存方法引用的类型,同时也是一种类型安全的函数指针;
理解委托的一种方式可以把委托的作用当作是给方法签名指定名称;
委托的定义类似于方法的定义,但没有方法体,定义的委托名前要加上关键字delegate;
因为定义委托基本上是定义一个新类,所以可以在定义类的任何地方定义委托,既可以在另一个类的内部定义委托,也可以在所有类的外部定义委托,还可以在命名空间中把委托定义为顶层对象。
根据定义的可见性,可以在委托定义上添加一般的访问修饰符:public、private和protected等。
一个委托实例压缩(或者称为封装)了一个方法称之为“一个可调用的实体” ,所以“一个可调用的实体”也就由这个委托实例本身和实例中封装的方法组成。
委托也可以包含多个方法,这种委托称为多播委托。
如果调用多播委托,就可以按顺序连续调用多个方法。为此,委托的签名就必须返回 void (否则,返回值应送到何处?)(当委托只包含一个方法的时候,其返回类型的声明可以参照所封装的方法,不一定必须是void)。实际上,如果编译器发现某个委托返回 void ,就会自动假定这是一个多播委托。
压缩方法的调用;
如: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)); }

浙公网安备 33010602011771号