C#委托和方法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#委托和方法相关的知识,希望对你有一定的参考价值。
using System;
using System.Collections.Generic;
using System.Text;
namespace Delegate
// 热水器
public class Heater
private int temperature;
public delegate void BoilHandler(int param); //声明委托
public event BoilHandler BoilEvent; //声明事件
// 烧水
public void BoilWater()
for (int i = 0; i <= 100; i++)
temperature = i;
if (temperature > 95)
if (BoilEvent != null) //如果有对象注册
BoilEvent(temperature); //调用所有注册对象的方法
// 警报器
public class Alarm
public void MakeAlert(int param)
Console.WriteLine("Alarm:嘀嘀嘀,水已经 0 度了:", param);
// 显示器
public class Display
public static void ShowMsg(int param) //静态方法
Console.WriteLine("Display:水快烧开了,当前温度:0度。", param);
class Program
static void Main()
Heater heater = new Heater();
Alarm alarm = new Alarm();
heater.BoilEvent += alarm.MakeAlert; //注册方法
heater.BoilEvent += (new Alarm()).MakeAlert; //给匿名对象注册方法
heater.BoilEvent += Display.ShowMsg; //注册静态方法
heater.BoilWater(); //烧水,会自动调用注册过对象的方法
public delegate void BoilHandler(int param); //声明委托
public event BoilHandler BoilEvent; //声明事件
为什么要声明这个委托,声明这个委托有什么意义,下面添加的都是事件 请解释下这两行代码
小弟在这谢谢各位了 小弟菜鸟
1、定义委托类型
[访问修饰符]delegate 返回类型 委托名(形参);
2、声明委托对象
委托名 委托实例名;
3、创建委托对象(确定与哪些方法进行绑定)
委托实例名=new 委托名(某个类的方法)
4、使用委托调用方法
委托实例名(实参)
委托注意事项:
1、委托和方法必须具有相同的参数。
2、委托可以调用多个方法,即一个委托对象可以维护一个可调用方法的列表而不是单独的一个方法,称为多路广播(多播)。
3、使用+=和-=运算实现方法的增加和减少
示例
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Delegate;
namespace Delegate
public delegate int Call(int num1, int num2);//第一步:定义委托类型
class SimpleMath
// 乘法方法
public int Multiply(int num1, int num2)
return num1 * num2;
// 除法方法
public int Divide(int num1, int num2)
return num1 / num2;
class Test
static void Main(string[] args)
Call objCall;//第二步:声明委托对象
// Math 类的对象
SimpleMath objMath = new SimpleMath();
// 第三步:创建委托对象,将方法与委托关联起来
objCall = new Call(objMath.Multiply);
Call objCall1 = new Call(objMath.Divide);
objCall += objCall1;//向委托增加一个方法
//objCall -= objCall1;//向委托减去一个方法 // 调用委托实例,先执行objMath.Multiply,然后执行objMath.Divide
int result = objCall(5, 3);
System.Console.WriteLine("结果为 0", result);
Console.ReadKey();
写法:
1、委托 委托名=new 委托(会调用的方法名); 委托名(参数);
2、委托 委托名 =会调用的方法名; 委托名(参数);
3、匿名方法
委托 委托名=delegate(参数)会调用的方法体;委托名(参数);
4、拉姆达表达式
委托 委托名=((参数1,。。参数n)=>会调用的方法体);委托名(参数);
5、用Action<T>和Func<T>,第一个无返回值
Func<参数1, 参数2, 返回值> 委托名= ((参数1,参数2) => 带返回值的方法体 );返回值=委托名(参数1,参数2);
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using @delegate;
namespace @delegate
public delegate int Call(int num1, int num2);
class SimpleMath
// 乘法方法
public static int Multiply(int num1, int num2)
return num1 * num2;
// 除法方法
public int Divide(int num1, int num2)
return num1 / num2;
class Test
static void Main(string[] args)
//--------------------第一种写法------------------------//
//Call objCall = new Call(SimpleMath.Multiply);
//Call objCall1 = new Call(new SimpleMath().Divide);
//--------------------第二种写法------------------------//
//Call objCall = SimpleMath.Multiply;
//Call objCall1 = new SimpleMath().Divide;
//--------------------第三种写法------------------------//
//Call objCall = delegate(int a, int b)
//
// return a * b;
//;
//Call objCall1 = delegate(int a, int b)
//
// return a / b;
//;
//--------------------第四种写法------------------------//
//Call objCall =((int a,int b)=> return a*b;);
//Call objCall1 = ((int a, int b) => return a / b; );
//--------------------第五种写法------------------------//
Func<int, int, int> objCall = ((a, b) => return a * b; );
Func<int, int, int> objCall1 = ((a, b) => return a / b; );
Action<int, int> ob = ((a, b) => Console.WriteLine(a * b); );
ob(5, 3);
//----------------------------------------------------//
int result = objCall(5, 3);
int result1 = objCall1(5, 3);
System.Console.WriteLine("结果1为 0,结果2为1", result,result1);
Console.ReadKey();
参考技术A 你要记住:事件是特殊的委托。
public delegate void BoilHandler(int param); //声明委托
解释:声明了一种委托类型——参数int,返回值void;比如这个程序中的MakeAlert和ShowMsg方法都是这种类型的所以可以用这个委托去代理他们;
public event BoilHandler BoilEvent; //声明事件
解释:声明了BoilHandler类型的事件,+=是多播委托的表示形式,这里面他就把MakeAlert,ShowMsg这些方法加进来了,这既是多播。
前两天也看了委托,应该是这么理解,希望对你有帮助,也希望高手指点。本回答被提问者采纳 参考技术B public delegate void BoilHandler(int param); //声明委托 声明了一个委托就是字面上的意思 如果不明白你可以理解为定义的一个类 可以接收 返回值为 void 参数为 int的函数
因为委托(可以理解为类)是不可以直接用的 所以需要实力化一个对象出来
public event BoilHandler BoilEvent; //声明事件 你可以理解为实列化一个对象出来
然后你可以用 BoilEvent 这个 事件(可以理解为对象)来注册事件 参考技术C C#里,所有的事件,都要定义处理事件需要使用的委托.
原理是这样的:
事件激发-->调用委托-->调用N个已注册的处理程序
处理事件的方法,必须要与事件声明时定义的委托一样(签名) 参考技术D 该帖已经讲述很清楚明白.
没必要再到这里来提问.
C#学习之初步理解委托事件匿名方法和Lambda
最经在学习LinqtoSql,然后扯到Lambda表达式,然后扯到匿名方法,然后扯到委托,最后扯到事件处理。。。后来发现对委托这个概念和事件处理这个过程理解得不是很清晰,遂得一下学习笔记。那里说得不对,请大家多多指教!
第一部分:理解委托
委托委托,顾名思义,就是类似于中间人的意思,有些事情你不做,委托别人去做,比如你想相亲,但你不想去主动约女孩子,那你可以交给媒婆去帮你约。
如果你学过C++,请把委托理解成函数指针,都是为了调用函数。函数指针可以调用符合该函数指针要求的函数。什么叫符合该函数指针要求?就是被调用的函数拥有和该函数指针一样的返回类型、参数的个数相同、对应参数的类型一致。
函数指针举例说明。int (*p)(int,int);定义了一个函数指针p,p只能调用 函数原型(或者说函数签名)是 返回类型为int、只有两个参数并且参数类型都是int的函数。
委托举例说明:delegate void MyDelegate(int a,int b);声明了一种委托类型 MyDelegate(委托有不同类型,就好像中间人有不同类型,你想相亲就找媒婆这种中间人,你想看风水,就找风水大师这种中间人),这种委托类型只能调用 返回类型是void、只有两个参数并且参数类型都是int的函数。跟函数指针是不是很像?
委托其实就是一个类,委托的基类是Delegate 类,只不过我们不能显示地从 Delegate 类派生出委托类(Delegate 类不是委托类型,它的派生类才是),这是给系统和编译器用的。只不过类实例化之后就叫对象,而委托实例化之后还是叫委托而已,另外实例化委托必须提供一个相对应的函数作为参数。
举例说明定义委托:(参考自:http://www.cnblogs.com/warensoft/archive/2010/03/19/1689806.html)
1、定义一个函数Max,函数签名位:返回类型为int,两个参数,参数类型都是int
int Max(int x,int y) {return x>y?x:y;}
2、创建一个委托类型(名字是MyDelegate),并声明该委托类型可以调用的函数的函数原型(函数签名)为:返回类型为int,两个参数,参数类型都是int。注意,委托是一个类,创建委托类型要放在函数外面
delegate int MyDelegate(int a,int b);
3.建立一个委托类的实例(或者说MyDelegate的实例),并指向要调用的方法,有两种方式:
//利用委托类的构造方法指定,这是最为常见的一种方式
MyDelegate md = new MyDelegate(Max);
//利用自动推断方式来指明要调用的方法,该形式更类型于函数指针
MyDelegate md = Max;
用第一种方式创建委托实例时必须提供一个函数签名符合该委托类型的函数作为参数。
4、利用委托类实例调用所指向的方法
int c = md(4,5);
总结:可以把委托理解成函数指针,可以调用函数签名和委托类型一致的函数
第二部分:事件处理(本文主要想表达对委托的理解,所以这部分以后再详说)
事件处理涉及到两个对象:一个是事件源(就是触发该事件的对象),另一个是事件接收者(提供了处理方法的类)。两者本无联系。
事件处理的过程:首先事件源触发了某事件,委托捕获到这件事(委托通过订阅该事件实现),委托调用事件接收类中的相应函数进行处理。
举例说明:this.button1.Click += new System.EventHandler(this.button1_Click);
事件源是button1,触发的事件是 按钮单击事件 Click,委托是 System.EventHandler ,事件处理函数是 button1_Click 。上面代码的意思是,System.EventHandler (委托)对 this.button1(事件源)的 Click (事件) 进行订阅,当this.button1 的Click事件发生时,委托接收事件源传过来的一些参数,接着调用 this.button1_Click (事件处理函数) 并把从事件源那里接收的参数传给该函数作为参数。
第三部分:匿名方法
匿名方法就是没有名字的方法(函数),既然没有名字,就是说只有在定义的时候能调用,在其他地方就不能调用了(没有名字啊,那就找不到嘛)。为什么 要用到匿名方法呢?调用函数是需要花销的,但有时候调用的一些方法很短小(例如一句话方法)、只完成很少的功能,这个时候就有点得不偿失了,此时就可以定 义一个匿名方法来完成这个功能了,而匿名方法作为内联代码,花销相对小很多。匿名方法都是和委托连在一起用的(以后还有lambda表达式),以前创建委 托实例时需要传递一个函数名给它作为参数,现在可以通过匿名方法直接把一段代码传进去了
定义匿名方法:用到delegate关键字,如:delegate(int a, int b){return a > b ? a : b ;} 代码定义了一个匿名方法,该方法的参数是 int a 和 int b ,方法体是 {return a > b ? a : b}。如果只是定义一个匿名方法没有意义,因为定义完过后你就再也不能用这个匿名方法,所以匿名方法要在定义的时候就马上使用。一般来说就是初始化委托 了。
使用匿名方法:
1 namespace DelegateTest
2 {
3 class Program
4 {
5 //创建委托类型
6 delegate int Mydelegate(int x, int y);
7 static void Main(string[] args)
8 {
9 //创建委托实例,指向匿名函数
10 Mydelegate mydelegate = delegate(int x,int y) { return x + y; };
11
12 //通过委托调用匿名方法
13 Console.WriteLine(mydelegate(3,2));
14
15 Console.ReadKey();
16 }
17 }
18 }
总结:匿名方法就是没有名字的方法,只能通过委托来被调用(这句话可能有误,匿名方法也可以直接订阅事件作为事件处理函数,当事件发生时就接收相应参数并执行函数体)。
第四部分:Lambda
上面说到可以通过匿名方法以内联代码的方式来简介地实现委托,但还有更简洁的方法,那就是用lambda表达式来代替匿名方法,在这里,lambda表达式就是匿名方法的简洁版。
Lambda表达式的语法如下:
(param1, param2 ...,paramN) =>
{
表达式1;
表达式2;
return 返回值;
}
param1, param2 ...,paramN 就是参数,不用确定类型,编译器会做这个工作,花括号了就是lambda表达式要执行的语句,如果对应的委托类型有返回值,那么就要有return 语句。
把第三部分那个匿名方法的例子改成用lambda表达式实现:
1 namespace DelegateTest
2 {
3 class Program
4 {
5 //创建委托类型
6 delegate int Mydelegate(int x, int y);
7 static void Main(string[] args)
8 {
9 //创建委托实例,指向匿名函数
10 // Mydelegate mydelegate = delegate(int x,int y) { return x + y; };
11
12 //通过委托调用匿名方法
13 // Console.WriteLine(mydelegate(3,2));
14
15 Mydelegate youdelegate = (x, y) => { return (x - y); };
16 Console.WriteLine(youdelegate(3, 2));
17
18 Console.ReadKey();
19 }
20 }
21 }
总结:匿名方法就是没有名字的函数,Lambda表达式就是匿名方法的简洁版(指的是用在委托上这方面,Lambda还有其他方面的用处),两者都只是让代码更简洁,但在更底层层次本质是一样的
以上是关于C#委托和方法的主要内容,如果未能解决你的问题,请参考以下文章