【C#学习】delegate(委托) 和 event(事件)
来源:互联网 发布:淘宝被公司屏蔽怎么办 编辑:程序博客网 时间:2024/06/07 20:03
C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针。委托(Delegate) 是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。在C#中方法不能作为参数直接传递,必须使用委托(用来委托方法)。delegate(委托)是一种特殊的引用类型,它将方法也作为特殊的对象封装起来,从而将方法作为变量、参数或者返回值传递。委托(Delegate)特别用于实现事件和回调方法。所有的委托(Delegate)都派生自 System.Delegate 类。使用一个委托有三个步骤:
- 定义委托
- 实例化委托
- 将指定的方法添加到委托对象中
例子:
delegate int plus(int x, int y); // 1. 定义委托 static void Main(string[] args) { plus del_p; // 2. 实例化委托 del_p = new plus(addition); // 3. 将方法添加到实例化委托对象中 int n = del_p(1, 2); Console.Write(n); } static int addition(int x, int y) { return x + y; }
C#允许直接把方法名赋给委托,所以下面的三种写法也正确:
plus del_p = new plus(addition); plus del_p2 = addition; del_p = addition;
委托完全可以被当做普通类型对待,比如可以加减、赋值、构建数组。
委托数组
委托可以构建数组,意味着一组同样返回类型和参数类型的方法。
delegate int MathFunc(int x, int y); static void Main(string[] args) { MathFunc[] fs = new MathFunc[] { substract, addition, product, division }; int n = fs[0](1, 2); // -1 } static int division( int x, int y) { return x / y; } static int substract(int x, int y) { return x - y; } static int addition(int x, int y) { return x + y; } static int product(int x, int y) { return x * y; }
委托的加减法/委托的多播(Multicasting of a Delegate)
一个委托对象可以封装多个方法,通过委托对象的合并(加法)实现。被合并的方法必须有相同的返回类型和参数类型。使用合并后的委托时,会依次将实参传入被合并的方法,最后的返回值以最后一个方法为准。
delegate int MathFunc(int x, int y); static void Main(string[] args) { MathFunc f; f = addition; f += substract; f += product; int n = f(1, 2); // 2 } static int division( int x, int y) { Console.WriteLine("division"); return x / y; } static int substract(int x, int y) { Console.WriteLine("substraction"); return x - y; } static int addition(int x, int y) { Console.WriteLine("addition"); return x + y; } static int product(int x, int y) { Console.WriteLine("product"); return x * y; }上面的代码会打印出:
addition
substraction
product
委托减法是加法的逆运算。如果被减委托中不含有减数委托,则不会对被减数造成任何影响,被减数减去自身为null,调用空委托会引发异常。总结下来委托加减法的几个结论:
- 委托加减null没有任何效果
- 委托减自身为null
- 减数如果没有包含在被减数中,则没有任何效果
在使用委托之前,应该判断委托是否为null。
传递委托
委托可以被作为以下方式传递
- 变量
- 方法参数
- 方法返回值
delegate int MathFunc(int x, int y); static void Main(string[] args) { MathFunc f = getAddFunc(); int n = f(2, 3); // 5 int n2 = add(f, 3, 4); // 7 } static int add(MathFunc f, int x, int y) { return f(x, y); } static MathFunc getAddFunc() { return addition; // or return new MathFunc(addition); }
匿名方法(delegate方法)
使用 delegate 关键字直接定义方法,和实例化委托不同,不使用 new 关键字来创建委托对象,而是直接定义方法参数和方法体。匿名方法并不是真的没有名称,而是指程序员无需命名。C#在编译时会给方法生成一个方法定义(包含方法名和参数列表),该方法实际上是当前类型的一个私有静态方法。
delegate int MathFunc(int x, int y); static void Main(string[] args) { MathFunc f = delegate (int x, int y) { return x + y; }; int n = f(1, 2); // 3 }
Lambda表达式
从C# 3.0 开始,可以用 lambda表达式替换匿名方法表达式,直接将一个 Lambda表达式赋给委托对象。注意Lambda表达式不能作为语句,必须为右值。Lambda表达式的参数和返回类型必须和委托一致。
delegate int MathFunc(int x, int y); static void Main(string[] args) { MathFunc f; f = (int x, int y) => { return x + y; }; int n = f(1, 2); // 3 }如果lambda表达式只有一个参数,则可以省略圆括号。Lambda表达式允许多种写法,以下写法等价:
something = (int x, int y) => { return x + y; }; something = (int x, int y) => x + y; something = (x, y) => x + y; something = (x, y) => { return x + y; };
Lambda表达式中没有用到的参数可以用 _ 代替。比如
something = (x, _) => x * 2;
MathFunc f; string str = "str"; f = (x, y) => { Console.Write(str); // 访问了外部的str return x + y; };如果Lambda表达式或者匿名delegate方法的参数名和外部变量冲突,则无法通过编译。
委托发布和订阅
基于委托多播的特性,可以实现 “发布者/订阅者”模式。发布者对象有一个委托成员,保存一系列别的类的实例(订阅者)的方法,一旦发布者触发(调用)了委托,就会把所有注册过的方法都依次调用依次,通知订阅者。比如有一个红绿灯,一旦红绿灯变色,就会通知所有车辆和行人,此时可以把车辆和行人的响应方法注册到红绿灯对象的一个 public 委托成员 OnColorChange 里,当红绿灯调用 OnColorChange 时,就会通知所有车辆,调用他们的响应函数。由于订阅者的类型和响应方法千奇百怪,可以高度定制针对一个事件(比如红绿灯变色)的不同对象的不同响应函数。
由于委托成员 OnColorChange 是公有的,一旦别的程序将委托置为空,或其他值,委托先前的修改就前功尽弃了。为了防止这种事情发生,C# 提供了 event来修饰(声明)委托成员。经过 event 修饰后,委托成员只能被 += 和 -= 修改,而不能用 = 修改。
阅读全文
0 0
- 【C#学习】delegate(委托) 和 event(事件)
- C#中的委托(Delegate)和事件(Event)
- C#中的委托(Delegate)和事件(Event)
- C#中的委托(Delegate)和事件(Event)
- C# 委托delegate 和 事件event
- C# 委托(delegate)和事件(event)详解
- c# event(事件)和delegate(委托)
- c#中的delegate(委托)和event(事件)
- c#中的delegate(委托)和event(事件)
- c#中的delegate(委托)和event(事件)
- c#中的delegate(委托)和event(事件)
- c#中的delegate(委托)和event(事件)
- c#中的delegate(委托)和event(事件)
- c#中的delegate(委托)和event(事件)
- c#中的delegate(委托)和event(事件)了
- c#中的delegate(委托)和event(事件)
- c#中的delegate(委托)和event(事件)
- C# delegate 委托 event 事件
- 一个简单的时钟View(关键点:Canvas的平移与旋转)
- 最富有的人trie树
- tomcat的调优(一)
- [HDU
- Scala入门学习之【Actor】
- 【C#学习】delegate(委托) 和 event(事件)
- ScriptManager和UpdatePanel控件的使用
- laravel安装错误
- Android架构设计之类协作
- Oracle总结一:数据库概述
- 位图
- 怎么调用私有构造函数(C++)
- UML类图
- HDU【1068】Girls And Boys(二分图+模板+最大独立集)