方法、委托和事件_第1页
方法、委托和事件_第2页
方法、委托和事件_第3页
方法、委托和事件_第4页
方法、委托和事件_第5页
已阅读5页,还剩28页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、 主要内容主要内容方法方法方法是代码复用的一种形式。定义一个方法,方法是代码复用的一种形式。定义一个方法,需要确认以下内容:需要确认以下内容:(1 1)方法名:见名知义)方法名:见名知义(2 2)参数名、参数类型、参数个数)参数名、参数类型、参数个数(3 3)方法的返回类型)方法的返回类型 voidvoid:方法不返回任何值。:方法不返回任何值。(4 4)方法体)方法体 returnreturn:回到主程序。:回到主程序。方法的重载方法的重载 一个类中允许出现多个同名的方法,只要参一个类中允许出现多个同名的方法,只要参数数个数个数或参数类型不同,编译器就认为这是两个或参数类型不同,编译器就认为

2、这是两个不同的方法。不同的方法。 int Add(int x,int y) int Add(int x,int y,int z) int Add(int x,double y) int Add(int u,int v) /参数名不同参数名不同 void Add(int x,int y) /返回类型不同返回类型不同方法的参数传递方法的参数传递值传递值传递引用传递引用传递(ref)输出参数输出参数(out)数组参数数组参数(params)值类型参数的按值传递值类型参数的按值传递 【例【例1】“按值传递按值传递” 传递的是实际参数的传递的是实际参数的一份拷贝,一份拷贝,是是C#参数传递的默认形式。下

3、面代码的输出结果是参数传递的默认形式。下面代码的输出结果是5。using System;using System;class Invokeclass Invoke void Change(int x) void Change(int x) x = 3; x = 3; public static void Main(String args) public static void Main(String args) int x = 5; int x = 5; Invoke e1 = new Invoke(); Invoke e1 = new Invoke(); e1.Change(x); e1.C

4、hange(x); Console.WriteLine(x); Console.WriteLine(x); 引用类型参数的按值传递引用类型参数的按值传递 class Invoke class Invoke int x; int x; void Change(Invoke obj) void Change(Invoke obj) obj.x = 3; obj.x = 3; public static void Main(String args) public static void Main(String args) Invoke e1 = new Invoke(); Invoke e1 = n

5、ew Invoke(); e1.x = 5; e1.x = 5; e1.Change(e1); e1.Change(e1); Console.WriteLine(e1.x); Console.WriteLine(e1.x); 【例【例2】下面代码的输出结果:】下面代码的输出结果:3。string引用类型的按值传递引用类型的按值传递 【例【例3】 string是引用类型,但是引用类型,但string字符串具字符串具有不变性,一旦被赋值,则它的内容不可改变。有不变性,一旦被赋值,则它的内容不可改变。下面代码的执行结果为:下面代码的执行结果为:old string。using System;usin

6、g System;class Programclass Program static void Main(string args) static void Main(string args) string str = old string; string str = old string; ChangeStr(str); ChangeStr(str); Console.WriteLine(str); Console.WriteLine(str); private static void ChangeStr(string oldStr) private static void ChangeStr

7、(string oldStr) oldStr = new string; oldStr = new string; 按引用传递按引用传递(ref) 【例【例4】 “引用传递引用传递”传递的是实际参数的传递的是实际参数的内存内存地址地址。引用传递参数使用关键字。引用传递参数使用关键字ref修饰。修饰。using System;using System;class Invokeclass Invoke /值类型参数按引用传递的情况 /值类型参数按引用传递的情况 static void ChangeByValue(ref int numValue) static void ChangeByValue

8、(ref int numValue) numValue = 10; numValue = 10; /引用类型参数按引用传递的情况 /引用类型参数按引用传递的情况 static void ChangeByRef(ref string numRef) static void ChangeByRef(ref string numRef) numRef = new string; numRef = new string; public static void Main(String args) public static void Main(String args) int num = 1; int

9、num = 1; string refStr = old string; string refStr = old string;输出参数输出参数(out) 【例【例5】输出参数用来从函数中返回结果。使】输出参数用来从函数中返回结果。使用前不需赋值,即使赋值了也会被忽略。用前不需赋值,即使赋值了也会被忽略。using System;using System;class Invokeclass Invoke static double CalculateCircle(double r, out double c) static double CalculateCircle(double r, ou

10、t double c) c = 2 * Math.PI * r; c = 2 * Math.PI * r; double s = Math.PI * r * r; double s = Math.PI * r * r; return s; return s; public static void Main(String args) public static void Main(String args) double circumference; double circumference; double radius = 3; double radius = 3; double area =

11、CalculateCircle(radius, out circumference); double area = CalculateCircle(radius, out circumference); Console.WriteLine(周长:0, circumference); Console.WriteLine(周长:0, circumference); Console.WriteLine(面积:0, area); Console.WriteLine(面积:0, area); Console.ReadKey(); Console.ReadKey(); 数组型参数数组型参数(params)

12、 C#提供了传递可变长度参数表的机制,使用提供了传递可变长度参数表的机制,使用params关键字来指定一个可变长的参数表。关键字来指定一个可变长的参数表。 params 参数必须是形参表中的最后一个参数。参数必须是形参表中的最后一个参数。using System;using System;class ParamArrayTestclass ParamArrayTest public static double Sum(params double numbers) public static double Sum(params double numbers) double total = 0.0

13、; double total = 0.0; foreach (double d in numbers) foreach (double d in numbers) total += d; total += d; return total; return total; public static void Main() public static void Main() double d1 = 10.0; double d1 = 10.0;委托委托l 委托相当于委托相当于C+中的函数指针,在程序中的函数指针,在程序运行时,可以使用委托调用不同的函数。运行时,可以使用委托调用不同的函数。l 委托使

14、得委托使得C#中的函数可以作为参数被传中的函数可以作为参数被传递。递。定义委托定义委托1、定义委托的语法如下:、定义委托的语法如下: 访问修饰符访问修饰符 delegate 返回值类型返回值类型 委托名称委托名称(参数参数1, 参数参数1, 参数参数n);【例如】【例如】 /不返回值,也没有参数的委托类型不返回值,也没有参数的委托类型BB public delegate void BB(); /返回返回string类型值,需要两个参数的委托类型类型值,需要两个参数的委托类型AA public delegate string AA(int a, string b);定义委托定义委托2、声明的位置

15、:、声明的位置:1)在类的内部定义;)在类的内部定义;2)在类外定义在类外定义3、根据定义的可见性,可以在委托定义上、根据定义的可见性,可以在委托定义上添加一般的访问修饰符:添加一般的访问修饰符:public、private、protected。 委托的用法委托的用法 【例【例1】请阅读下面代码,理解委托的基本用法。】请阅读下面代码,理解委托的基本用法。using System;/在类外,定义一个委托public delegate int myDelegateHandler(int a, int b);public class A public static int Max(int a, in

16、t b) return (a b) ? a : b; public static int Min(int a, int b) return (a b) ? a : b; public class B委托的用法委托的用法 【例【例2】下面代码通过委托,实现了通用函数定】下面代码通过委托,实现了通用函数定积分的计算。积分的计算。using System;class Functions public static double F1(double x) return 2 * x + 1; public static double F2(double x) return x * x; class In

17、tegral委托的用法委托的用法 【例【例3】下面代码实现了根据姓名、薪水对员工】下面代码实现了根据姓名、薪水对员工对象的排序输出。对象的排序输出。using System;class Sorter public delegate bool CompareDelegate(Object e1, Object e2); public static void Sort(Object sortArray, CompareDelegate compareMethod) for (int i = 0; i sortArray.Length-1; i+) for (int j = 0; j sortArr

18、ay.Length-i-1; j+) if (compareMethod(sortArrayj,sortArrayj+1) Object temp = sortArrayj; sortArrayj = sortArrayj + 1; sortArrayj + 1 = temp;匿名函数匿名函数*l 创建委托实例时,不仅可以使用已有创建委托实例时,不仅可以使用已有的函数,还可以直接使用匿名函数。的函数,还可以直接使用匿名函数。l 匿名函数可以使用代码块内定义的变匿名函数可以使用代码块内定义的变量,也可以使用代码块外定义的变量。量,也可以使用代码块外定义的变量。l 使用匿名函数,可以简化代码。使用

19、匿名函数,可以简化代码。匿名函数匿名函数* * 【例【例4】下面代码通过定义匿名函数,实现通用】下面代码通过定义匿名函数,实现通用函数定积分的计算。函数定积分的计算。using System;public class Integral public delegate double IntegralDelegate(double x); public static double GetIntegral(double a, double b, IntegralDelegate f) const int section = 1000; double detal = (b - a) / section

20、; double area = 0.0; for (int i = 0; i ”连接参数和连接参数和 方法体,增强了匿名函数的可读性。方法体,增强了匿名函数的可读性。Lambda表达式表达式* 【例【例5】下面代码通过】下面代码通过Lambda表达式,实现通表达式,实现通用函数定积分的计算。用函数定积分的计算。using System;class Integral public delegate double IntegralDelegate(double x); public static double GetIntegral(double a, double b, IntegralDele

21、gate f) const int section = 1000; double increment = (b - a) / 1000; double area = 0.0; for (int i = 0; i = section; i+) area = area + f(a + increment * i) * increment;多路广播委托多路广播委托l委托可以包含多个方法,这种委托称为委托可以包含多个方法,这种委托称为多路广播委托。多路广播委托。l如果调用多路广播委托,就可以按顺序如果调用多路广播委托,就可以按顺序连续调用多个方法。连续调用多个方法。l通过使用通过使用“+”、”+=”,

22、实现往委托中,实现往委托中添加方法;通过使用添加方法;通过使用“-”、“-=”,实现从,实现从委托中删除方法调用。委托中删除方法调用。多路广播委托多路广播委托 【例【例6】请分析下面代码的执行结果。】请分析下面代码的执行结果。using System;class MathOperations public static void MultiplyByTwo(double value) double result = value * 2; Console.WriteLine(Multiplying by 2: 0 gives 1, value, result); public static vo

23、id Square(double value) double result = value * value; Console.WriteLine(Squaring: 0 gives 1, value, result); public static void DivideByTwo(double value)事件事件C#的事件涉及两类角色:的事件涉及两类角色:事件发布者:发布事件的对象;事件发布者:发布事件的对象;事件订阅者:捕获事件并对事件进行响应的事件订阅者:捕获事件并对事件进行响应的对象。对象。C#的事件是一个特殊的多路广播委托。的事件是一个特殊的多路广播委托。事件事件1、定义事件:、定义

24、事件:访问修饰符访问修饰符 event 委托类型委托类型 事件名事件名public event EventHandler birthday 访问修饰符一般定义为访问修饰符一般定义为public,因为事件订阅,因为事件订阅者需要对事件进行订阅与取消操作。者需要对事件进行订阅与取消操作。 事件定义中需要声明委托类型,它既可以是事件定义中需要声明委托类型,它既可以是自定义的委托类型,也可以是自定义的委托类型,也可以是Net类库中预定义类库中预定义的委托类型的委托类型EventHandler。事件事件2、订阅和取消事件:、订阅和取消事件: 事件订阅者需要订阅事件发布者发布的事件订阅者需要订阅事件发布者

25、发布的事件,以便事件被触发时接收消息并作出事件,以便事件被触发时接收消息并作出处理。处理。 使用使用“+=”订阅事件订阅事件 使用使用“-=”取消事件取消事件事件事件 【例【例1 1】寿星发出】寿星发出“过生日过生日”消息的通知,朋友收到通知后给予消息的通知,朋友收到通知后给予祝福。本例使用祝福。本例使用“自定义委托类型自定义委托类型”来定义事件。来定义事件。using System;/1、寿星类,充当事件发布者class Longevity /自定义委托类型 public delegate void BirthdayHandler(string msg); /使用自定义委托类型Birthda

26、yHandler,定义事件 public event BirthdayHandler BirthdayEvent; /发出事件通知 public void SendMessage(string msg) /判断是否绑定了事件处理方法 if (BirthdayEvent!= null) /触发事件 BirthdayEvent(msg); 事件事件 【例【例2 2】寿星发出】寿星发出“过生日过生日”消息的通知,朋友收到通知后给予祝福。消息的通知,朋友收到通知后给予祝福。本例使用本例使用.Net.Net类库中预定义的委托类型类库中预定义的委托类型EventHandlerEventHandler来定义

27、事件。来定义事件。using System;/1、寿星类,充当事件发布者class Longevity /使用预定义委托类型EventHandler,定义事件 /EventHandler的定义为: /public delegate void EventHandler(object sender, EventArgs e); public event EventHandler BirthdayEvent; /发出事件通知 public void SendMessage(string msg) /判断是否绑定了事件处理方法 if (BirthdayEvent!= null) /触发事件 Conso

28、le.WriteLine(msg); BirthdayEvent(this,new EventArgs(); 事件事件EventHandler是是.NET类库预定义的委托类型,类库预定义的委托类型,定义如下:定义如下:public delegate void EventHandler(object sender, EventArgs e);sender:事件发布者:事件发布者e:负责保存事件数据,为:负责保存事件数据,为EventArgs类型。标类型。标准的准的EventArgs并不包含任何事件数据,因此并不包含任何事件数据,因此EventHandler适用于不生成数据的事件。适用于不生成数据

29、的事件。事件事件由于由于 EventHandler适用于处理适用于处理不包含不包含事件数据的事件事件数据的事件,【例,【例2】代码的执行结果】代码的执行结果与【例与【例1】不同。】不同。通过派生通过派生EventArgs 类可以实现对事件类可以实现对事件数据的传递。派生类中提供保存事件数据数据的传递。派生类中提供保存事件数据所需的全部字段或属性,这样发布者可以所需的全部字段或属性,这样发布者可以将特定的数据发送给订阅者将特定的数据发送给订阅者。事件事件 【例【例3 3】寿星发出】寿星发出“过生日过生日”消息的通知,朋友收到通知后给予消息的通知,朋友收到通知后给予祝福。本例中通过派生祝福。本例中

30、通过派生EventArgsEventArgs类达到与【例类达到与【例1 1】相同的效果。】相同的效果。using System;/扩展EventArgs类,使其带有事件数据class BirthdayEventArgs : EventArgs public string Message; public BirthdayEventArgs(string msg) Message = msg; /寿星类,充当事件发布者class Longevity /自定义委托类型,委托包含两个参数 public delegate void BirthdayHandler(object sender,BirthdayEventArgs e); public event BirthdayHandler BirthdayEvent; /发出事件通知 public void SendMessage(string msg)事件处理机制事件处理机制 win

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论