C# 委托详解汇总
委托的存在是因为,我们有时候需要将一个函数作为另一个函数的参数,这时就要用的委托(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所引用的方法 //string res1 = str1(); //是一样的, Console.WriteLine(res); //示例:使用委托作为参数 GetAString getastring = GetName; Console.WriteLine(getastring()); getastring = GetAge; Console.WriteLine(getastring()); Console.ReadKey(); } static string GetName() { string str = "这是GetName方法"; return str; } static string GetAge() { string str = "这是GetAge方法"; return str; } }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
系统预定义的委托:
除了我们自己定义的委托之外,系统还给我们提供过来一个内置的委托类型,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); } }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
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"; } }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
多播委托
多播委托:我们把包含多个函数的委托称为多播委托(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"); } }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
文章来源: czhenya.blog.csdn.net,作者:陈言必行,版权归原作者所有,如需转载,请联系作者。
原文链接:czhenya.blog.csdn.net/article/details/78203647
- 点赞
- 收藏
- 关注作者
评论(0)