首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

委托和事件?该如何处理

2012-01-26 
委托和事件???接触C#语言有一段时间了,对于委托和事件还是一知半解,各位朋友能帮我详细介绍下关于这两方面

委托和事件???
接触C#语言有一段时间了,对于委托和事件还是一知半解,各位朋友能帮我详细介绍下关于这两方面的东西吗?最好能附上代码实例。先谢谢了。

[解决办法]
bookstore.cs

--------------------------------------------
// 版权所有 (C) Microsoft Corporation。保留所有权利。

// bookstore.cs
using System;

// 用于处理书店的一组类:
namespace Bookstore
{
using System.Collections;

// 描述图书列表中的一本书:
public struct Book
{
public string Title; // 书名。
public string Author; // 作者。
public decimal Price; // 价格。
public bool Paperback; // 是平装本吗?

public Book(string title, string author, decimal price, bool paperBack)
{
Title = title;
Author = author;
Price = price;
Paperback = paperBack;
}
}

// 声明一个用于处理书的委托类型:
public delegate void ProcessBookDelegate(Book book);

// 维护一个图书数据库。
public class BookDB
{
// 列出数据库中的所有图书:
ArrayList list = new ArrayList();

// 向数据库中添加图书:
public void AddBook(string title, string author, decimal price, bool paperBack)
{
list.Add(new Book(title, author, price, paperBack));
}

// 对每本平装图书调用传入委托来进行处理:
public void ProcessPaperbackBooks(ProcessBookDelegate processBook)
{
foreach (Book b in list)
{
if (b.Paperback)
// 调用该委托:
processBook(b);
}
}
}
}

// 使用 Bookstore 类:
namespace BookTestClient
{
using Bookstore;

// 计算图书总价格和平均价格的类:
class PriceTotaller
{
int countBooks = 0;
decimal priceBooks = 0.0m;

internal void AddBookToTotal(Book book)
{
countBooks += 1;
priceBooks += book.Price;
}

internal decimal AveragePrice()
{
return priceBooks / countBooks;
}
}

// 测试图书数据库的类:
class Test
{
// 打印书名。
static void PrintTitle(Book b)
{
Console.WriteLine( " {0} ", b.Title);
}

// 下面开始执行。
static void Main()
{
BookDB bookDB = new BookDB();

// 用一些书初始化数据库:
AddBooks(bookDB);

// 打印所有平装本的书名:
Console.WriteLine( "Paperback Book Titles: ");
// 创建一个与静态方法 Test.PrintTitle 关联的
// 新委托对象:
bookDB.ProcessPaperbackBooks(new ProcessBookDelegate(PrintTitle));

// 使用 PriceTotaller 对象
// 获取平装本的平均价格:
PriceTotaller totaller = new PriceTotaller();
// 创建一个与对象 totaller 的非静态方法
// AddBookToTotal 关联的新委托对象:
bookDB.ProcessPaperbackBooks(new ProcessBookDelegate(totaller.AddBookToTotal));
Console.WriteLine( "Average Paperback Book Price: ${0:#.##} ",
totaller.AveragePrice());
}

// 用一些测试图书初始化图书数据库:
static void AddBooks(BookDB bookDB)
{
bookDB.AddBook( "The C Programming Language ",
"Brian W. Kernighan and Dennis M. Ritchie ", 19.95m, true);
bookDB.AddBook( "The Unicode Standard 2.0 ",
"The Unicode Consortium ", 39.95m, true);
bookDB.AddBook( "The MS-DOS Encyclopedia ",


"Ray Duncan ", 129.95m, false);
bookDB.AddBook( "Dogbert 's Clues for the Clueless ",
"Scott Adams ", 12.00m, true);
}
}
}



[解决办法]
// 版权所有 (C) Microsoft Corporation。保留所有权利。

// events1.cs
using System;
namespace MyCollections
{
using System.Collections;

// 用于对更改通知进行挂钩的委托类型。
public delegate void ChangedEventHandler(object sender, EventArgs e);

// 一个类,其作用与 ArrayList 相似,
// 但在每次列表更改时发送通知。
public class ListWithChangedEvent: ArrayList
{
// 一个事件,每当列表元素更改时,客户端可利用该事件
// 获得通知。
public event ChangedEventHandler Changed;

// 调用 Changed 事件;每当列表更改时调用
protected virtual void OnChanged(EventArgs e)
{
if (Changed != null)
Changed(this, e);
}

// 重写可更改列表的某些方法;
// 在每个重写后调用事件
public override int Add(object value)
{
int i = base.Add(value);
OnChanged(EventArgs.Empty);
return i;
}

public override void Clear()
{
base.Clear();
OnChanged(EventArgs.Empty);
}

public override object this[int index]
{
set
{
base[index] = value;
OnChanged(EventArgs.Empty);
}
}
}
}

namespace TestEvents
{
using MyCollections;

class EventListener
{
private ListWithChangedEvent List;

public EventListener(ListWithChangedEvent list)
{
List = list;
// 将“ListChanged”添加到“List”中的 Changed 事件。
List.Changed += new ChangedEventHandler(ListChanged);
}

// 每当列表更改时就会进行以下调用。
private void ListChanged(object sender, EventArgs e)
{
Console.WriteLine( "This is called when the event fires. ");
}

public void Detach()
{
// 分离事件并删除列表
List.Changed -= new ChangedEventHandler(ListChanged);
List = null;
}
}

class Test
{
// 测试 ListWithChangedEvent 类。
public static void Main()
{
// 创建新列表。
ListWithChangedEvent list = new ListWithChangedEvent();

// 创建一个类,用于侦听列表的更改事件。
EventListener listener = new EventListener(list);

// 在列表中添加和移除项。
list.Add( "item 1 ");
list.Clear();
listener.Detach();
}
}
}


[解决办法]
using System;

namespace DelegateAndEvent
{
/**//// <summary>
/// 声明一个委托,用于代理一系列 "无返回 "及 "不带参 "的自定义方法
/// </summary>
/// <param name= "sender "> 事件源 </param>
/// <param name= "e "> 不包含任何事件数据的 EventArgs </param>
public delegate void MyEventHandler(object sender, EventArgs e);

/**//// <summary>
/// 人类
/// </summary>
public class Person
{
/**//// <summary>
/// 在开始移动时发生
/// </summary>
public event MyEventHandler OnBeginMove;

/**//// <summary>


/// 在到达目的地时发生
/// </summary>
public event MyEventHandler OnEndMove;

private string _name;

/**//// <summary>
/// 名字
/// </summary>
public string Name
{
get { return _name; }
set { _name = value; }
}

/**//// <summary>
/// 移动
/// <remarks> 封装了触发事件的方法 </remarks>
/// </summary>
/// <param name= "place "> 目的地 </param>
public void Move(Place place)
{
// OnBeginMove 事件在这里被触发了
if (OnBeginMove != null)
OnBeginMove(this, EventArgs.Empty);

OnMove(place);

// OnEndMove 事件在这里被触发了
if (OnEndMove != null)
OnEndMove(this, EventArgs.Empty);
}

private void OnMove(Place place)
{
Console.WriteLine( "我走啊走啊走啊走. ");
Console.WriteLine( "我已经走到 x={0} y={1} 的位置 ", place.X, place.Y);
}
}
}

Place 类源代码:

using System;

namespace DelegateAndEvent
{
public class Place
{
private int _x;
private int _y;

public Place() { }

public Place(int x, int y)
{
this._x = x;
this._y = y;
}

public int X
{
get { return _x; }
set { _x = value; }
}

public int Y
{
get { return _y; }
set { _y = value; }
}

}
}

客户端原代码:

using System;

namespace DelegateAndEvent
{
public class Program
{
static void Main(string[] args)
{
// 创建一个 Person 的新实例
Person Yyw = new Person();

// 将事件与委托绑定
// 这里使用了命名委托
Yyw.OnBeginMove += new MyEventHandler(Yyw_OnBeginMove);
// 这里使用了匿名委托(C# 2.0 的新特性)
Yyw.OnEndMove += delegate(System.Object sender, System.EventArgs e)
{
Console.WriteLine( "我已经走到了尽头 ");
};

Place place = new Place(10, 20);

// 到那边去
Yyw.Move(place);

Console.Read();
}

static void Yyw_OnBeginMove(object sender, EventArgs e)
{
Console.WriteLine( "我要开始走动了 ");
}
}
}


程序输出结果:

我要开始走动了
我走啊走啊走啊走....
我已经走到 x=10 y=20 的位置
我已经走到了尽头


[解决办法]
你可以当委托是一个智能型函数指针。
[解决办法]
zhqs1000(子鱼) ( ) 信誉:100
举的例子很经典了
就是自己的事让别人帮着做就是委托
a,有套书
b,是中介
c,想要书
这个模型当中b就是委托,他是沟通买主与卖主的桥梁。
[解决办法]
委托相当于C++的回调,C的函数指针,但委托是类型安全的,它可以使你的代码通用性更好(例如:用委托实现冒泡排序法,可以让所有的类型(整型,浮点型,引用型等)),所以要用委托,
[解决办法]
to zhqs:
bookDB.ProcessPaperbackBooks(new ProcessBookDelegate (totaller.AddBookToTotal));


Console.WriteLine( "Average Paperback Book Price: ${0:#.##} ",
totaller.AveragePrice());
第一句对吗?
totaller.AddBookToTotal这个执行返回的是什么,和委托所定义的不一样啊
[解决办法]
应该这么理解
委托是个中介,通过中介能够执行它所关联的方法。委托声明必须和它所托方法的声明一样。具体语法我就不说了。
事件必须由委托来声明。是一种特殊的委托用法。
[解决办法]
我就觉得这事儿只是概念问题.

委托用于定义事件及异步调用等,其实就是类似于函数指针.有实例清楚一点
[解决办法]
事件是用户请求(即事件),委托是程序员(实际上是程序里边的函数)请求。当然了,事件和委托的内容都是需要开发人员来决定的!
[解决办法]
应该这么理解
委托是个中介,通过中介能够执行它所关联的方法。委托声明必须和它所托方法的声明一样。具体语法我就不说了。
事件必须由委托来声明。是一种特殊的委托用法。

热点排行