委托

来源:互联网 发布:网络阅读利弊的辩论 编辑:程序博客网 时间:2024/05/22 09:32

在前面我们说过委托的定义和作用,它可以指向有返回值和参数的方法。
在C#中,系统内置(预定义)了两个委托类型,分别是Action委托Func委托,这两个委托类型可以满足编程中大部分需求,不需要我们自己去定义新的委托类型。

Action委托:它可以指向一个没有返回值,没有参数的方法。但是它可以通过泛型来指向一个没有返回值,但是有参数的方法,最多支持有16个参数的方法。
Action委托示例:

class Program    {        static void PrintString()        {            Console.WriteLine("Hello World");        }        static void PrintInt(int i)        {        }        static void PrintDoubleInt(int i1, int i2)        {            Console.WriteLine(i1+i2);        }        static void PrintString(string str)        {            Console.WriteLine(str);        }        static void Main(string[] args)        {            Action a = PrintString; //默认的Action委托是只能指向没有返回值和没有参数的方法            Action<int> a1 = PrintInt; //通过泛型能够指向有参数的方法            Action<int, int> a2 = PrintDoubleInt; //通过泛型能够指向有多个参数的方法,最多16个参数            Action<string> a3 = PrintString; //Action委托使用泛型也能够重载,系统会自动寻找匹配的方法        }    }

Func委托:它可以指向一个有返回值,没有参数的方法。同样的它也可以通过泛型来指向有最多16个参数的方法,但是必须要有返回值。
Func委托示例:

class Program    {        static int Test1()        {            return 1;        }        static int Test2(string str)        {            Console.WriteLine(str);            return 100;        }        static int Test3(int i, int j)        {            return i + j;        }        static void Main(string[] args)        {            Func<int> a = Test1; //Func委托可以指向有返回值的方法            Console.WriteLine(a());            Func<string, int> a1 = Test2; //同时他也可以指向有参数也有返回值的方法,返回值放在最后一个            Func<int, int, int> a2 = Test3; //和Action委托一样,它能够指向有多个参数的方法            int res = a2(5, 8);            Console.WriteLine(res);            Console.ReadKey();        }    }

多播委托
我们之前自己定义的委托和系统内置的委托,都是只能够指向一个方法,但是C#中有多播委托可以指向多个方法。
多播委托可以通过“+=”和“-=”来增加或减少该委托所指向的方法。但是当多播委托中有多个方法时,它是按顺序来调用多个方法的,并且多播委托只能得到调用的最后一个方法的结果,所以一般来说我们把多播委托的返回类型都声明为void。
在多播委托中,我们可以取得其中所有的方法,然后通过遍历来调用其中的方法,但是要注意的是,多播委托实质上是包含一个逐个调用的委托集合,如果我们通过委托调用的其中一个方法抛出了异常,程序就会停止,后面的代码不再执行。
实例:

class Program    {        static void Test1()        {            Console.WriteLine("Test1");        }        static void Test2()        {            Console.WriteLine("Test2");        }        static void Main(string[] args)        {            //如果一个委托没有指向任何方法的时候,调用的话就会出现异常,相当于空指针            Action a = Test1;            //a = Test2;//相当于更改引用,而不是同时指向两个方法            a += Test2;            //a -= Test2;//在多播委托中减去一个方法            a();            Delegate[] delegates = a.GetInvocationList();//取得委托中的所有方法            foreach (Delegate de in delegates)            {                de.DynamicInvoke();//单独调用其中的方法            }            Console.ReadKey();        }    }
原创粉丝点击