C#高级编程 委托和事件: 回调(callback)函数是Windows 编程的一个重要部分。如果您具备C 或C++编程背景,应该就曾 在许多Windows API 中使用过回调。Visual Basic添加了AddressOf关键字后,开发人员就可以利用以 前一度受到限制的API 了。回调函数实际上是方法调用的指针,也称为函数指针,是一个非常强大的 编程特性。.NET 以委托的形式实现了函数指针的概念。它们的特殊之处是,与C 函数指针不同,.NET 委托是类型安全的。这说明,C中的函数指针只不过是一个指向存储单元的指针,我们无法说出这个 指针实际指向什么,像参数和返回类型等就更无从知晓了。如本章所述,.NET 把委托作为一种类型 安全的操作。本章后面将学习.NET如何将委托用作实现事件的方式 ### C#高级编程_委托和事件 #### 一、委托 **1.1 委托的概念** 在C#中,委托是一种引用类型的数据结构,它允许我们将方法当作参数进行传递。简而言之,委托是一种封装了方法签名的类型安全的函数指针。通过这种方式,我们可以灵活地将不同的方法绑定到相同的接口上,从而实现更为动态和灵活的编程方式。 **1.2 在C#中声明委托** 为了使用委托,我们需要先定义它。定义委托的基本语法如下: ```csharp delegate returnType DelegateName(type1 arg1, type2 arg2, ...); ``` 这里的`returnType`是被封装的方法的返回类型,`DelegateName`是我们定义的委托名称,而`type1 arg1, type2 arg2, ...`则是方法的参数列表。例如: ```csharp delegate int AddDelegate(int x, int y); ``` 此代码定义了一个名为`AddDelegate`的委托,它接受两个整型参数,并返回一个整型值。 **1.3 在C#中使用委托** 一旦定义了委托,我们就可以创建委托的实例,并将相应的方法绑定到这个实例上。例如: ```csharp public int Add(int a, int b) { return a + b; } AddDelegate add = new AddDelegate(Add); int result = add(3, 4); // 结果为7 ``` 这里,我们定义了一个名为`Add`的方法,并将其绑定到了`AddDelegate`类型的实例`add`上。随后我们可以通过`add`调用`Add`方法。 **1.4 简单的委托示例** 为了进一步理解委托的工作原理,我们来看一个简单的示例。假设我们有一个`Calculator`类,其中包含多个数学运算方法,比如加法、减法等。我们可以定义一个委托来代表这些方法: ```csharp public delegate int Operation(int x, int y); public class Calculator { public int Add(int a, int b) { return a + b; } public int Subtract(int a, int b) { return a - b; } } class Program { static void Main(string[] args) { Calculator calc = new Calculator(); Operation op = calc.Add; Console.WriteLine(op(5, 3)); // 输出8 op = calc.Subtract; Console.WriteLine(op(5, 3)); // 输出2 } } ``` 在上述代码中,我们定义了一个名为`Operation`的委托,它可以代表任何接受两个整型参数并返回整型结果的方法。接着我们创建了一个`Calculator`类的实例,并将类中的`Add`和`Subtract`方法绑定到`Operation`委托上。 **1.5 多播委托** 多播委托是指能够绑定多个方法的委托。当调用这样的委托时,所有绑定的方法都会被依次执行。这对于需要通知多个对象的情况非常有用,例如在GUI编程中处理事件。定义和使用多播委托的示例如下: ```csharp public delegate void MultiDelegate(); class Program { static void MethodA() { Console.WriteLine("Method A called."); } static void MethodB() { Console.WriteLine("Method B called."); } static void Main(string[] args) { MultiDelegate md = new MultiDelegate(MethodA); md += MethodB; md(); // 输出"Method A called." 和 "Method B called." } } ``` **1.6 匿名方法** 在C#中,还可以使用匿名方法来定义委托。匿名方法是一种没有名称的方法,可以在创建委托实例的同时定义。这种方式在早期版本的C#中非常流行,但随着Lambda表达式的引入,匿名方法的使用逐渐减少。下面是一个使用匿名方法的示例: ```csharp public delegate void SimpleDelegate(); class Program { static void Main(string[] args) { SimpleDelegate d = delegate { Console.WriteLine("Hello, World!"); }; d(); } } ``` **1.7 Lambda表达式** Lambda表达式是C#中用于简化匿名方法的一种方式,它的语法更加简洁。例如: ```csharp public delegate int MathOperation(int x, int y); class Program { static void Main(string[] args) { MathOperation add = (x, y) => x + y; Console.WriteLine(add(3, 4)); // 输出7 } } ``` **1.8 协变和抗变** 协变(covariance)和抗变(contravariance)是C#中两个重要的概念,用于描述类型之间关系的灵活性。协变允许将派生类型的实例赋值给基类型的变量;抗变则允许将基类型的实例赋值给派生类型的变量。这两种特性对于泛型和委托来说尤为重要,使得我们能够在保持类型安全的前提下,提高代码的灵活性和重用性。 ### 二、事件 **2.1 事件的概念** 事件是在对象内部发生的情况,它对外部的观察者提供了通知机制。在C#中,事件通常是通过委托来实现的。当对象内部发生特定事件时,会触发该事件,从而调用已注册的事件处理程序。 **2.2 生成事件** 为了生成一个事件,我们需要定义一个委托类型,然后基于这个委托类型定义事件。例如: ```csharp public delegate void MessageHandler(string message); public class Publisher { public event MessageHandler MessagePublished; public void PublishMessage(string msg) { OnMessagePublished(msg); } protected virtual void OnMessagePublished(string msg) { MessageHandler handler = MessagePublished; if (handler != null) { handler(msg); } } } ``` 在上述代码中,我们定义了一个名为`Publisher`的类,它包含一个名为`MessagePublished`的事件。该事件基于`MessageHandler`委托定义。`PublishMessage`方法负责触发事件,而`OnMessagePublished`方法则负责实际调用事件处理程序。 **2.3 事件的订阅与取消订阅** 为了订阅事件,我们需要定义一个事件处理方法,并将其添加到事件中。同时,我们也需要提供取消订阅的方法。例如: ```csharp public class Subscriber { public void Subscribe(Publisher publisher) { publisher.MessagePublished += HandleMessage; } public void Unsubscribe(Publisher publisher) { publisher.MessagePublished -= HandleMessage; } private void HandleMessage(string message) { Console.WriteLine("Received message: " + message); } } ``` 在上述代码中,我们定义了一个名为`Subscriber`的类,它包含`Subscribe`和`Unsubscribe`方法来管理对`Publisher`对象的事件订阅。此外,还定义了一个名为`HandleMessage`的事件处理方法,当事件被触发时,该方法会被调用。 ### 小结 通过本文的讲解,我们可以看出委托和事件是C#中非常重要的特性,它们为我们提供了强大的功能,使我们的代码更加灵活、模块化和易于维护。无论是多线程编程、GUI编程还是通用库的设计,委托和事件都能发挥重要作用。理解和掌握委托和事件的概念及使用方法,对于成为一名优秀的C#开发者至关重要。
剩余22页未读,继续阅读
- 粉丝: 2
- 资源: 9
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助