C# 委托详解汇总

举报
陈言必行 发表于 2021/08/13 23:26:14 2021/08/13
【摘要】 委托的存在是因为,我们有时候需要将一个函数作为另一个函数的参数,这时就要用的委托(Delegate)机制,,, 委托用关键字delegate声明,他实际上定义了一种“函数类型”,明确规定了函数参数类型和返回值类型。(即无参数无返回值的委托,只能接受无参数无返回值的方法,反之亦然,,) 声明委托: 在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

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。