温故知新(7)委托(一)delegate、Action、Func

来源:互联网 发布:淘宝卖办公用品 编辑:程序博客网 时间:2024/06/03 20:50

首先有以下几个问题,我们带这问题来一一对照解决

1、委托是什么,可以用来做什么

2、在什么情况下使用委托

3、委托与事件的关系又是什么

1、委托

委托就是当前程序接收到一个字段以后,它本身并不具有处理这个字段的能力,需要委托给专门的、私有静态的方法去处理,等待这个方法回传的值即可;

委托是一个类型,这个类型可以赋值一个方法的使用(委托可以放在命名空间下,或者类下面)

声明: 

delegate string GetString();

案例1

namespace Test1{    delegate void GetFun();    class Program    {        private delegate string GetString();        private delegate void GetFun();        static void Main(string[] args)        {            int x = 100;            GetString a = new GetString(x.ToString);            string str = a();//通过委托实例去调用x中的ToString方法            GetFun fun = Method;//通过委托把Methed这个方法赋值给fun            fun();            Console.WriteLine(str);            Console.ReadKey();        }        static void Method()        {            Console.WriteLine("xxxxxx");        }    }}
委托的赋值
GetAString a = new GetAString(x.ToString);// 只需要把方法名给一个委托的构造方法就可以了GetAString a = x.ToString; //也可以把方法名直接给委托的实例


案例2

(使用委托类型作为方法的参数)

namespace Test1{    class Program    {        private delegate void PrintString();        static void Main(string[] args)        {            PrintString method = Method;            PrintStr(method);            Console.ReadKey();        }        static void PrintStr(PrintString print)        {            print();//相当于间接的调用了Method();        }        static void Method()        {            Console.WriteLine("xxxxxx");        }    }}

Action委托和Func委托

除了我们自己定义的委托之外,系统还给我们提供过来一个内置的委托类型,Action和Func
Action委托引用了一个void返回类型的方法,T表示方法参数,先看Action委托有哪些
Action
Action<in T>
Action<in T1,in T2>
Action<in T1,in T2 ....  inT16>
Func引用了一个带有一个返回值的方法,它可以传递0或者多到16个参数类型,和一个返回类型
Func<out TResult>
Func<in T,out TResult>
Func<int T1,inT2,,,,,,in T16,out TResult>

Action委托

案例

namespace Test1{    class Program    {        static void Main(string[] args)        {            Action a = PrintString;            a();            Console.ReadKey();        }        static void PrintString()        {            Console.WriteLine("xxxxxx");        }    }}
Action<int> a;//定义了一个委托类型,这个类型可以指向一个没有返回值,有一个int参数的方法。
Action<int,int> a;//指向一个有两个int参数的方法
Action 可以后面通过泛型去指定action指向的方法的多个参数的类型,参数的类型跟action后面声明的委托类型是对应着的

namespace Test1{    class Program    {        static void Main(string[] args)        {            Action<string> a = PrintString;            a("xxxxxx");            Action<int, int> b = Add;            b(10, 20);                        Console.ReadKey();        }        static void PrintString(string str)        {           Console.WriteLine(str);        }                static void Add(int a,int b)        {            Console.WriteLine(a + b);        }    }}

Func委托

案例

Func<int>//Func中的泛型类型指定的是方法中的返回值类型
Func<int,int>//泛型前面的是参数类型,最后一个是返回值类型
namespace Test1{    class Program    {        static void Main(string[] args)        {            Func<string> a = PrintString;            string str = a();            Func<int, int, int> b = Add;            int c = b(10, 20);            Console.WriteLine(str);            Console.WriteLine(c);            Console.ReadKey();        }        static string PrintString()        {            return "xxxxxx";        }                static int Add(int a,int b)        {            return a + b;        }    }}

多播委托

前面使用的委托都只包含一个方法的调用,但是委托也可以包含多个方法,这种委托叫做多播委托。使用多播委托就可以按照顺序调用多个方法,多播委托只能得到调用的最后一个方法的结果,一般我们把多播委托的返回类型声明为void。
【注】当一个委托没有指向任何方法的时候,调用的话会出现异常null,如果调用的方法,前面的出现了异常,后面的不会被调用。

案例

namespace Test1{    class Program    {        static void Main(string[] args)        {            Action a = Test1;            a += Test2;//表示添加一个委托的引用            a -= Test1;//表示减去一个委托的引用            a();            Console.ReadKey();        }        static void Test1()        {            Console.WriteLine("Test1");        }        static void Test2()        {            Console.WriteLine("Test2");        }    }}


取得多播委托中所有方法的委托

namespace Test1{    class Program    {        static void Main(string[] args)        {            Action a = Method1;            a += Method2;            Delegate[] delegates = a.GetInvocationList();            foreach (Delegate d in delegates)            {                d.DynamicInvoke(null);            }            Console.ReadKey();        }        private static void Method2()        {            Console.WriteLine("Method1");        }        private static void Method1()        {            Console.WriteLine("Method2");        }    }}

阅读全文
0 0
原创粉丝点击