介绍.NET中的委派(Delegates)之一
来源:网络收集 责任编辑:栏目编辑 发表时间:2013-07-02 00:15 点击:次
回调函数
回调函数的确是至今为止最有用的编程机制之一。C运行时的qsort函数利用回调函数对数组元素进行排序。在Windows中,回调函数更是窗口过程,钩子过程,异步过程调用,以及目前Microsoft .NET框架所必需的,在整个回调过程中自始至终地使用回调方法。人们可以注册回调方法以获得加载/卸载通知,未处理异常通知,数据库/窗口状态修改通知,文件系统修改通知,菜单项选择,完成的异步操作通知,过滤一组条目等等。
在C/C++中,一个函数的地址就是内存地址。这个地址不会附带任何其它赋加信息,如函数的参数个数,参数类型,函数的返回值类型以及这个函数的调用规范。简言之,C/C++回调函数不是类型安全的。
在.NET框架中,回调函数所受到的重用与它在Windows非受控编程中一样。不同的是在.NET框架中提供了一种叫委派(delegates)的类型安全机制。我们先来研究一下委派的声明。下面的代码展示了如何声明,创建和使用委派:
//
using System;
using System.WinForms; // 在beta2版本中为:System.Windows.Forms
using System.IO;
class Set {
private Object[] items;
public Set(Int32 numItems) {
items = new Object[numItems];
for (Int32 i = 0; i < numItems; i++)
items[i] = i;
}
// 定义 Feedback,类型为delegate
// (注意: 这个类型在Set类中是嵌套的)
public delegate void Feedback(
Object value, Int32 item, Int32 numItems);
public void ProcessItems(Feedback feedback) {
for (Int32 item = 0; item < items.Length; item++) {
if (feedback != null) {
// 一旦指定了回调,便调用它们
feedback(items[item], item + 1, items.Length);
}
}
}
}
class App {
[STAThreadAttribute]
static void Main() {
StaticCallbacks();
InstanceCallbacks();
}
static void StaticCallbacks() {
// 创建一个Set对象,其中有五个项目
Set setOfItems = new Set(5);
// 处理项目,feedback=null
setOfItems.ProcessItems(null);
Console.WriteLine();
// 处理项目,feedback=Console
setOfItems.ProcessItems(new Set.Feedback(App.FeedbackToConsole));
Console.WriteLine();
// 处理项目,feedback =MsgBox
setOfItems.ProcessItems(new Set.Feedback(App.FeedbackToMsgBox));
Console.WriteLine();
// 处理项目,feedback = console AND MsgBox
Set.Feedback fb = null;
fb += new Set.Feedback(App.FeedbackToConsole);
fb += new Set.Feedback(App.FeedbackToMsgBox);
setOfItems.ProcessItems(fb);
Console.WriteLine();
}
static void FeedbackToConsole(
Object value, Int32 item, Int32 numItems) {
Console.WriteLine("Processing item {0} of {1}: {2}.",
item, numItems, value);
}
static void FeedbackToMsgBox(
Object value, Int32 item, Int32 numItems) {
MessageBox.Show(String.Format("Processing item {0} of {1}: {2}.",
item, numItems, value));
}
static void InstanceCallbacks() {
//创建一个Set对象,其中有五个元素
Set setOfItems = new Set(5);
// 处理项目,feedback=File
App appobj = new App();
setOfItems.ProcessItems(new Set.Feedback(appobj.FeedbackToFile));
Console.WriteLine();
}
void FeedbackToFile(
Object value, Int32 item, Int32 numItems) {
StreamWriter sw = new StreamWriter("Status", true);
sw.WriteLine("Processing item {0} of {1}: {2}.",
item, numItems, value);
sw.Close();
}
}
//
注意代码最上面的Set类。假设这个类包含一组将被单独处理的项目。当你创建Set对象时,将它要操纵的项目数传递给它的构造函数。然后构造函数再创建对象(Objects)数组并初始化每一个整型值。
另外,Set类定义了一个公共的委派,这个委派指出某个回调函数的签名。在这个例子中,委派Feedback 确定了一个带三个参数的方法(第一个参数为Object,第二和第三个参数都是Int32类型)并且返回void。在某种意义上,委派很像C/C++中表示某个函数地址的类型定义(typedef)。
此外,Set类定义了一个公共方法:ProcessItems。这个方法有一个参数feedback——一个对委派Feedback 对象的引用。ProcessItem
回调函数的确是至今为止最有用的编程机制之一。C运行时的qsort函数利用回调函数对数组元素进行排序。在Windows中,回调函数更是窗口过程,钩子过程,异步过程调用,以及目前Microsoft .NET框架所必需的,在整个回调过程中自始至终地使用回调方法。人们可以注册回调方法以获得加载/卸载通知,未处理异常通知,数据库/窗口状态修改通知,文件系统修改通知,菜单项选择,完成的异步操作通知,过滤一组条目等等。
在C/C++中,一个函数的地址就是内存地址。这个地址不会附带任何其它赋加信息,如函数的参数个数,参数类型,函数的返回值类型以及这个函数的调用规范。简言之,C/C++回调函数不是类型安全的。
在.NET框架中,回调函数所受到的重用与它在Windows非受控编程中一样。不同的是在.NET框架中提供了一种叫委派(delegates)的类型安全机制。我们先来研究一下委派的声明。下面的代码展示了如何声明,创建和使用委派:
//
using System;
using System.WinForms; // 在beta2版本中为:System.Windows.Forms
using System.IO;
class Set {
private Object[] items;
public Set(Int32 numItems) {
items = new Object[numItems];
for (Int32 i = 0; i < numItems; i++)
items[i] = i;
}
// 定义 Feedback,类型为delegate
// (注意: 这个类型在Set类中是嵌套的)
public delegate void Feedback(
Object value, Int32 item, Int32 numItems);
public void ProcessItems(Feedback feedback) {
for (Int32 item = 0; item < items.Length; item++) {
if (feedback != null) {
// 一旦指定了回调,便调用它们
feedback(items[item], item + 1, items.Length);
}
}
}
}
class App {
[STAThreadAttribute]
static void Main() {
StaticCallbacks();
InstanceCallbacks();
}
static void StaticCallbacks() {
// 创建一个Set对象,其中有五个项目
Set setOfItems = new Set(5);
// 处理项目,feedback=null
setOfItems.ProcessItems(null);
Console.WriteLine();
// 处理项目,feedback=Console
setOfItems.ProcessItems(new Set.Feedback(App.FeedbackToConsole));
Console.WriteLine();
// 处理项目,feedback =MsgBox
setOfItems.ProcessItems(new Set.Feedback(App.FeedbackToMsgBox));
Console.WriteLine();
// 处理项目,feedback = console AND MsgBox
Set.Feedback fb = null;
fb += new Set.Feedback(App.FeedbackToConsole);
fb += new Set.Feedback(App.FeedbackToMsgBox);
setOfItems.ProcessItems(fb);
Console.WriteLine();
}
static void FeedbackToConsole(
Object value, Int32 item, Int32 numItems) {
Console.WriteLine("Processing item {0} of {1}: {2}.",
item, numItems, value);
}
static void FeedbackToMsgBox(
Object value, Int32 item, Int32 numItems) {
MessageBox.Show(String.Format("Processing item {0} of {1}: {2}.",
item, numItems, value));
}
static void InstanceCallbacks() {
//创建一个Set对象,其中有五个元素
Set setOfItems = new Set(5);
// 处理项目,feedback=File
App appobj = new App();
setOfItems.ProcessItems(new Set.Feedback(appobj.FeedbackToFile));
Console.WriteLine();
}
void FeedbackToFile(
Object value, Int32 item, Int32 numItems) {
StreamWriter sw = new StreamWriter("Status", true);
sw.WriteLine("Processing item {0} of {1}: {2}.",
item, numItems, value);
sw.Close();
}
}
//
注意代码最上面的Set类。假设这个类包含一组将被单独处理的项目。当你创建Set对象时,将它要操纵的项目数传递给它的构造函数。然后构造函数再创建对象(Objects)数组并初始化每一个整型值。
另外,Set类定义了一个公共的委派,这个委派指出某个回调函数的签名。在这个例子中,委派Feedback 确定了一个带三个参数的方法(第一个参数为Object,第二和第三个参数都是Int32类型)并且返回void。在某种意义上,委派很像C/C++中表示某个函数地址的类型定义(typedef)。
此外,Set类定义了一个公共方法:ProcessItems。这个方法有一个参数feedback——一个对委派Feedback 对象的引用。ProcessItem
最新推荐更多>>>
- 发表评论
-
- 最新评论 更多>>