问题:
你组合了多个委托来创建一个多播委托。当调用这个多播委托时,将依次调用其中的每个委托。你需要施加更多的控制。例如,调用每个委托的顺序,只触发一个委托子集或者基于前一个委托成功与否来触发每个委托。此外,你需要能够单独处理每个委托的返回值。
解决方案:
使用GetInvocationList 方法获得Delegate 对象的数组。接下来,使用for 循环(如果以非标准顺序进行枚举)或foreach 循环(如果以标准顺序进行枚举)遍历这个数组。然后可以逐个调用数组中的每个Delegate 对象,并且可以获取每个委托的返回值。
在C# 中,所有委托类型都支持多播;也就是说,如果这样设置,那么任何委托实例在每次调用时都可以调用多个方法。在本范例中,我们使用术语多播(multicast)来描述设置为调用多个方法的委托。
下面的方法创建一个名为allInstances 的多播委托,然后使用GetInvocationList 以逆序逐一调用每个委托。Func<int> 泛型委托用于创建返回int 的委托实例。
public static void InvokeInReverse()
{
Func<int> myDelegateInstance1 = TestInvokeIntReturn.Method1;
Func<int> myDelegateInstance2 = TestInvokeIntReturn.Method2;
Func<int> myDelegateInstance3 = TestInvokeIntReturn.Method3;
Func<int> allInstances =
myDelegateInstance1 +
myDelegateInstance2 +
myDelegateInstance3;
Console.WriteLine("Fire delegates in reverse");
Delegate[] delegateList = allInstances.GetInvocationList();
foreach (Func<int> instance in delegateList.Reverse())
{
instance();
}
}
注意,为了翻转使用GetInvocationList 得到的委托列表,我们使用了IEnumerable<T> 的扩展方法Reverse,以枚举通常产生数据项时的相反顺序获得它们。
如下面的方法所示, 通过触发每隔一个的委托, 你不必调用列表中的所有委托。
InvokeEveryOtherOperation 使用此处为IEnumerable<T> 创建的名为EveryOther 的扩展方法,该方法从枚举中每隔一个数据项进行返回。
(注:如果使用单播委托,并且对它调用GetInvocationList,将会获得一个包含单一委托实例的列表。)
public static void InvokeEveryOtherOperation()
{
Func<int> myDelegateInstance1 = TestInvokeIntReturn.Method1;
Func<int> myDelegateInstance2 = TestInvokeIntReturn.Method2;
Func<int> myDelegateInstance3 = TestInvokeIntReturn.Method3;
Func<int> allInstances = myDelegateInstanc