C# 委托详解汇总

来源:互联网 发布:知客是什么工作 编辑:程序博客网 时间:2024/06/05 06:56

委托的存在是因为,我们有时候需要将一个函数作为另一个函数的参数,这时就要用的委托(Delegate)机制,,,

委托用关键字delegate声明,他实际上定义了一种“函数类型”,明确规定了函数参数类型和返回值类型。(即无参数无返回值的委托,只能接受无参数无返回值的方法,反之亦然,,)

声明委托
在C#中使用一个类分两个阶段,首选定义这个类,告诉编译器这个类由什么字段和方法组成的,然后使用这个类实例化对象。在我们使用委托的时候,也需要经过这两个阶段,首先定义委托,告诉编译器我们这个委托可以指向哪些类型的方法,然后,创建该委托的实例

定义委托的语法如下:
delegate void MethodInvoker(int x);
定义了一个委托叫做MethodInvoker,这个委托可以指向什么类型的方法呢?

这个方法要带有一个int类型的参数,并且方法的返回值是void的。
定义一个委托要定义方法的参数和返回值,使用关键字delegate定义。
定义委托的其他案例:
delegate double TwoLongOp(long first,long second);
delegate string GetAString();


.NET编译器严格检查函数类型和未做的类型是否匹配,只有完全匹配才能进行转换转换之后的委托实例作为参数,传递给调用它的函数,
利用委托可以实现以函数为参数,提高程序的通用性,委托用关键字的delegate声明,实际上创建,一种委托相当于创建一个从System.Delegate派生出来的类,类中有一个调用列表,列表中包含着委托函数的引用,与c++的函数指针相比委托是一个在类型安全的方式。

小例:

using System;namespace 委托{    class Program    {        //定义委托   返回值string类型,无参数        private delegate string GetAString();        static void Main(string[] args)        {            //======================构造函数使用委托====================            int x = 410;            //使用委托声明实例  str指向了Tostring方法            GetAString str = new GetAString(x.ToString);            string res = str();  //委托类型调用方法            Console.WriteLine(res);            //======================直接赋值法使用委托====================            GetAString str1 = x.ToString;            string res1 = str1.Invoke();   //通过invoke方法调用str1所引用的方法            Console.WriteLine(res);            //示例:使用委托作为参数            GetAString getastring = GetName;            Console.WriteLine(getastring());            getastring = GetAge;            Console.WriteLine(getastring());            Console.ReadKey();        }        static string GetName()        {            string str = "This is Get Name Method";            return str;        }        static string GetAge()        {            string str = "This is Get Age Method";            return str;        }    }}

系统预定义的委托:
除了我们自己定义的委托之外,系统还给我们提供过来一个内置的委托类型,Action和Func
Action委托引用了一个void返回类型的方法,T表示方法参数,先看Action委托有哪些

Action委托示例

namespace Action委托{    class Program    {        static void Main(string[] args)        {            //系统内置的一个委托类型,它指向一个没有返回值,没有参数的方法            Action method1 = Show;            method1();            //利用泛型,定义没有返回值,带参数的委托            Action<string> method2 = Show;            method2("CZHENYA");            //系统会自动识别重载方法,,Action可以通过泛型来添加参数(最多支持16个参数),但是一定没有返回值            Console.ReadLine();        }        static void Show()        {            Console.WriteLine("Hello Czhenya");        }        static void Show(String name)        {            Console.WriteLine("HELLO"+name);        }    }}

Func引用了一个带有一个返回值的方法,它可以传递0或者多到16个参数类型,和一个返回类型

//func委托实例namespace Func委托{    class Program    {        static void Main(string[] args)        {            //func 中的泛型是指定的方法的返回值类型,,            Func<int> method = Show1;            Console.WriteLine("方法的返回值是:"+ method());            //func 中的泛型是最后一个类型必须是函数的返回值类型,前面的是方法参数类型可以输入(0-16)            Func<int,string> method1 = Show2;            Console.WriteLine(method1(20));            Console.ReadKey();        }        static int Show1()        {            return 111;        }        static string Show2(int age)        {            Console.WriteLine(age);            return "Czhenya";        }    }}

多播委托

多播委托:我们把包含多个函数的委托称为多播委托(Muiticast Delegate),所有被委托函数的引用都存储在多播委托类的调用列表中,当调用多播委托时,会按顺序依次调用列表中的所有函数。
向多播委托中注册函数的语法为:
通过+=运算符向多播委托中注册函数
从多播委托中删除函数的语法:使用-=运算符,,
注:多播委托只能得到调用的最后一个方法的结果,一般多播委托的返回值只能是void ,,,

namespace 多播委托{    class Program    {        static void Main(string[] args)        {            //多播委托               Action method = Text1;            method += Text2;            //method();            //method -= Text1;                //当委托没有指向任意一个方法的时候,会报出异常,,,            //获得委托中的所有方法            Delegate[] delegates = method.GetInvocationList();            //遍历出来,挨个调用            foreach (Delegate item in delegates)            {                //item();                item.DynamicInvoke();            }            Console.ReadKey();        }        static void Text1()        {            Console.WriteLine("Text1");        }        static void Text2()        {            Console.WriteLine("Text2");        }    }}
原创粉丝点击