zoukankan      html  css  js  c++  java
  • 使用GetInvocationList对委托链进行更多的控制

    委托链中所有项都会被调用,因为委托类型的 Invoke 方法包含了对数组中的所有项进行遍历的代码。这是一个很简单的算法。尽管这个简单的算法足以应付很多情形,但也有它的局限性。例如,除了最后一个返回值,其他所有回调方法的返回值都会被丢弃。但局限并不止于此。如果被调用的委托中有一个抛出了异常或阻塞了相当长一段时间,会出现什么情况呢?由于这个简单的算法是顺序调用链中的每一个委托,所以一个委托对象出现问题,链中后续的所有对象都调用不了啊。显然,这个算法还不够健壮性

    所以 MulticastDelegate(派生于 Delegate)类提供了一个实例方法 GetInvocationList,用于显式调用链中的每一个委托,并允许你使用需要的任何算法。

    GetInvocationList 方法操作从 MulticastDelegate 派生的对象,返回包含 Delegate 引用的一个数组,其中每个引用都指向链中的一个委托对象。在内部,GetInvocationList 构造并初始化一个数组,让它的每个元素都引用链中的一个委托,然后返回对该数组的引用。如果 _invocationList 字段为null,返回的数组就只有一个元素,该元素引用链中唯一的委托,即委托实例本身。

    如下代码演示:

     1 using System;
     2 using System.Text;
     3 
     4 namespace _17._5._2取得对委托链调用的更多控制
     5 {
     6     class Program
     7     {
     8         // 定义委托来查询一个组件的状态
     9         private delegate string GetStatus();
    10 
    11         static void Main(string[] args)
    12         {
    13             // 声明空委托链
    14             GetStatus getStatus = null;
    15 
    16             // 构造3个组件,将它们的状态方法添加到委托链中
    17             getStatus += new GetStatus(new Light().SwitchPosition);
    18             getStatus += new GetStatus(new Fan().Speed);
    19             getStatus += new GetStatus(new Speaker().Volume);
    20 
    21             // 显式整理好的状态报告,反映这3个组件的状态。
    22             Console.WriteLine(GetComponentStatusReport(getStatus));
    23 
    24             Console.ReadKey();
    25         }
    26 
    27         // 该方法查询几个组件并返回状态报告
    28         private static string GetComponentStatusReport(GetStatus status)
    29         {
    30             // 如果委托链为空,就不进行任何操作
    31             if (status == null) return null;
    32 
    33             // 用下面的变量来创建状态报告
    34             StringBuilder report = new StringBuilder();
    35 
    36             // 获得一个数组,其中每个元素都是链中的委托
    37             Delegate[] arrayOfDelegates = status.GetInvocationList();
    38 
    39             // 遍历数组中每一个委托
    40             foreach (GetStatus getStatus in arrayOfDelegates)
    41             {
    42                 try
    43                 {
    44                     // 获得一个组件的状态字符串
    45                     report.AppendFormat("{0}{1}{1}", getStatus(), Environment.NewLine);
    46                 }
    47                 catch (InvalidOperationException e)
    48                 {
    49                     // 在状态报告中为该组件生成一个错误记录。
    50                     object component = getStatus.Target;
    51 
    52                     report.AppendFormat(
    53                         "Failed to get status from {1}{2}{0}    Error: {3}{0}{0}",
    54                         Environment.NewLine,
    55                         ((component == null) ? "" : component.GetType() + "."),
    56                         getStatus.Method.Name,
    57                         e.Message);
    58                 }
    59             }
    60 
    61             return report.ToString();
    62         }
    63     }
    64 
    65     // 定义一个灯组件
    66     internal sealed class Light
    67     {
    68         // 该方法返回灯的状态
    69         public string SwitchPosition()
    70         {
    71             return "The light is off";
    72         }
    73     }
    74 
    75     // 定义一个风扇组件
    76     internal sealed class Fan
    77     {
    78         // 该方法返回风扇组件
    79         public string Speed()
    80         {
    81             throw new InvalidOperationException("The fan broke due to overheating");
    82         }
    83     }
    84 
    85     // 定义一个扬声器组件
    86     internal sealed class Speaker
    87     {
    88         // 该方法返回扬声器的状态
    89         public string Volume()
    90         {
    91             return "The volume is loud";
    92         }
    93     }
    94 }
  • 相关阅读:
    606. Construct String from Binary Tree
    696. Count Binary Substrings
    POJ 3255 Roadblocks (次短路)
    POJ 2823 Sliding Window (单调队列)
    POJ 1704 Georgia and Bob (博弈)
    UVa 1663 Purifying Machine (二分匹配)
    UVa 10801 Lift Hopping (Dijkstra)
    POJ 3281 Dining (网络流之最大流)
    UVa 11100 The Trip, 2007 (题意+贪心)
    UVaLive 4254 Processor (二分+优先队列)
  • 原文地址:https://www.cnblogs.com/dalovess/p/6947368.html
Copyright © 2011-2022 走看看