Effective C# Item 21: Express Callbacks with Delegates
2006-11-23 08:49
399 查看
Effective C# Item 21: Express Callbacks with Delegates
爸爸:“儿子,去把院子里的草割一下。我看会儿报。”
儿子:“爸爸,我把院子打扫干净了。”
儿子:“爸爸,我给割草机加了油。”
儿子:“爸爸,割草机发动不了。”
爸爸:“我来发动它。”
儿子:“爸爸,我把草割好了。”
这个就是回调处理的例子。爸爸给儿子指派一项任务,儿子报告任务进展。在爸爸等待儿子完成工作的时候,并没有阻塞他自己正在进行的活动。如果儿子有什么重要(即便是不重要的)事情,可以打断爸爸的活动来报告情况。回调被用在服务器端和客户端的异步通信。这或许会包含多线程操作,或者仅仅是简单的提供同步更新的入口点。回调处理在C#语言中是通过委托来实现的。
委托为回调提供了一个安全的定义。尽管我们一般将委托用于处理事件,但这并不是它唯一发挥作用的地方。当我们需要配置类之间的通信,又希望实现较接口而言的松耦合时,我们就可以使用委托。委托可以让我们可以在运行时期对目标进行配置并通知多个客户端。委托是一个包含方法引用的对象。通过使用委托,我们可以于一个或多个客户端对象通信,在运行时期改变它们的配置。
多路广播委托可以在一个函数被调用时触发多个添加到委托中的函数。对于这种方式我们应当注意两点:首先它对异常不安全,其次它的返回值将是最后一次相应函数的返回值。
在多路广播委托的响应中每个目标都必须要成功的被调用。委托不会捕获任何相关的异常。因此一旦有目标抛出异常,则整个委托响应链就会被中断。
同样类似的问题还会出现在返回值上。我们可以为委托定义返回值,在回调的时候检查这些返回:
public delegate bool ContinueProcessing();
public void LengthyOperation(ContinueProcessing pred)
ContinueProcessing cp = new ContinueProcessing (CheckWithUser);
cp += new ContinueProcessing(CheckWithUser);
c.LengthyOperation(cp);
委托的返回值将会是多路广播委托链中最后一个函数的返回值。所有的其它返回值都被忽略了,就如同本例中的CheckWithUser()。
我们可以通过手工来调用每个委托。我们创建的每个委托包含一个委托的列表。我们需要遍历这个列表来检查委托链中的返回值。
public delegate bool ContinueProcessing();
public void LengthyOperation(ContinueProcessing pred)
{
bool bContinue = true;
foreach (ComplicatedClass cl in _container)
{
c1.DoLengthOperation();
foreach(ContinueProcessing pr in pred.GetInvocationList())
{
bCountinue &= pr();
}
if (false == bCountinue)
{
return;
}
}
}
这样我们就从语法上定义了每个委托必须为true
委托提供了在运行时使用回调的最好方法,对客户端也没有特殊的要求。我们可以在运行时处理委托目标,同时也可以支持多路广播委托。在.Net中客户端回调应当使用委托来实现。
译自 Effective C#:50 Specific Ways to Improve Your C# Bill Wagner著
回到目录
对于委托,我又想起来那个经典的.Net睡前故事...
爸爸:“儿子,去把院子里的草割一下。我看会儿报。”
儿子:“爸爸,我把院子打扫干净了。”
儿子:“爸爸,我给割草机加了油。”
儿子:“爸爸,割草机发动不了。”
爸爸:“我来发动它。”
儿子:“爸爸,我把草割好了。”
这个就是回调处理的例子。爸爸给儿子指派一项任务,儿子报告任务进展。在爸爸等待儿子完成工作的时候,并没有阻塞他自己正在进行的活动。如果儿子有什么重要(即便是不重要的)事情,可以打断爸爸的活动来报告情况。回调被用在服务器端和客户端的异步通信。这或许会包含多线程操作,或者仅仅是简单的提供同步更新的入口点。回调处理在C#语言中是通过委托来实现的。
委托为回调提供了一个安全的定义。尽管我们一般将委托用于处理事件,但这并不是它唯一发挥作用的地方。当我们需要配置类之间的通信,又希望实现较接口而言的松耦合时,我们就可以使用委托。委托可以让我们可以在运行时期对目标进行配置并通知多个客户端。委托是一个包含方法引用的对象。通过使用委托,我们可以于一个或多个客户端对象通信,在运行时期改变它们的配置。
多路广播委托可以在一个函数被调用时触发多个添加到委托中的函数。对于这种方式我们应当注意两点:首先它对异常不安全,其次它的返回值将是最后一次相应函数的返回值。
在多路广播委托的响应中每个目标都必须要成功的被调用。委托不会捕获任何相关的异常。因此一旦有目标抛出异常,则整个委托响应链就会被中断。
同样类似的问题还会出现在返回值上。我们可以为委托定义返回值,在回调的时候检查这些返回:
public delegate bool ContinueProcessing();
public void LengthyOperation(ContinueProcessing pred)
ContinueProcessing cp = new ContinueProcessing (CheckWithUser);
cp += new ContinueProcessing(CheckWithUser);
c.LengthyOperation(cp);
委托的返回值将会是多路广播委托链中最后一个函数的返回值。所有的其它返回值都被忽略了,就如同本例中的CheckWithUser()。
我们可以通过手工来调用每个委托。我们创建的每个委托包含一个委托的列表。我们需要遍历这个列表来检查委托链中的返回值。
public delegate bool ContinueProcessing();
public void LengthyOperation(ContinueProcessing pred)
{
bool bContinue = true;
foreach (ComplicatedClass cl in _container)
{
c1.DoLengthOperation();
foreach(ContinueProcessing pr in pred.GetInvocationList())
{
bCountinue &= pr();
}
if (false == bCountinue)
{
return;
}
}
}
这样我们就从语法上定义了每个委托必须为true
委托提供了在运行时使用回调的最好方法,对客户端也没有特殊的要求。我们可以在运行时处理委托目标,同时也可以支持多路广播委托。在.Net中客户端回调应当使用委托来实现。
译自 Effective C#:50 Specific Ways to Improve Your C# Bill Wagner著
回到目录
对于委托,我又想起来那个经典的.Net睡前故事...
相关文章推荐
- Effective C#之21:Express Callbacks with Delegates
- Item 24: Express Callbacks with Delegates(Effective C#)
- Effective C# Item13: Initialize Static Class Members with Static Constructiors
- Effective C# Item 26: Implement Ordering Relations with IComparable and IComparer
- Effective C# Item 22: Define Outgoing Interface With Events
- Item 54: Familiarize yourself with the standard library, including TR1(Effective C++)
- Item 21: Don't try to return a reference when you must return an object(Effective C++)
- More Effective C# Item2 : 恰到好处的定义约束
- Effective C# Item20:明辨接口实现和虚方法重写
- Effective Java,Item2——Consider a builder when faced with many constructor parameters
- Effective C# Item13:使用静态构造器初始化静态类成员
- Effective C# Item 28: Avoid Conversion Operators
- More Effective C# Item7 : 不要为基类或者接口创建泛型的特殊实现
- Effective C# Item6:明辨值类型和引用类型的使用场合
- Effective C# Item39 : 使用.NET验证
- Effective JavaScript Item 10 避免使用with
- EffectiveC++ Item21
- 读书笔记 effective c++ Item 21 当你必须返回一个对象的时候,不要尝试返回引用
- Effective C# Item 10: Understand the Pitfalls of GetHashCode()
- Effective c# Item3:操作符is或as优于强制转型