将 Delegate[] 传递给方法
Passing a Delegate[] to a method
我正在尝试解构另一个编码员编写的方法以查看它是如何工作的,但它有点令人困惑
我们有一个将 Action 作为参数的委托。
private delegate void FunctionDelegate(Action next);
然后在构造函数中调用一个函数,该函数将这些委托的数组作为参数并执行数组中的每个值
LoadInSeries(LoadRoleAreaHours, LoadTableData);
函数看起来像这样
private void LoadInSeries(params FunctionDelegate[] _delegates)
{
var Delegates = new List<FunctionDelegate>(_delegates);
Func<Action, Action> creator = null;
creator = delegate(Action inner)
{
if (Delegates.Count > 0)
{
FunctionDelegate L = Delegates.First();
Delegates.RemoveAt(0);
Action next = delegate { L(inner); };
return creator(next);
}
else return inner;
};
Action outer = creator(null);
if (outer != null)
outer();
}
目的是将一系列函数链接起来,每个函数调用下一个函数,但使用多播委托并将每个函数添加到调用列表中不是很容易吗。
这段代码有什么不同吗?
没有好的Minimal, Complete, and Verifiable code example,就不可能完全理解代码。最值得关注的是您的代码示例包含一个神秘的 L()
方法,我们不知道其行为。 FunctionDelegate = Delegates.First();
语句也有问题。充其量,FunctionDelegate
标识符指的是 class 字段或 属性;在最坏的情况下,该语句甚至不会编译。无论哪种方式,都没有证据表明从输入列表中删除的委托对象实际上曾被调用过。
所以即使要回答这个问题,也必须做出一些基本假设,这些假设可能正确也可能不正确。
也就是说,在最好的情况下——代码在 L()
方法中隐藏了一些可怕的、复杂的机制,最终能够为当前调用调用委托creator
委托 — 您正在查看的代码并非像 MulticastDelegate
那样简单地按顺序调用委托。相反,代码构建了对 L()
方法的调用链,将每个委托实例按顺序传递给该方法。
由于您没有向我们展示 L()
方法,因此无法说明 代码实际做了什么。我同意,如果 L()
所做的只是调用您传递给它的委托,那么这段代码看起来像是一种非常复杂的方法来调用一组委托。但是,让编写代码的人从怀疑中获益,这仅仅意味着 L()
可能做了一些事情,而不是简单地调用委托。
当然,代码的作者可能不值得怀疑。在那种情况下,不仅使用多播委托会更简单,而且 最简单 实现只会遍历数组,以所需顺序调用每个委托。但是我这么说并没有真正了解代码的作用。我只是假设它打算对传递给它的委托做一些有用的事情。您发布的代码中没有证据支持这种慷慨的假设。
给我们完整的图片,可以提供更明确的答案。如果不知道 L()
是什么,或者传递的委托的目标方法中可能存在哪些副作用,则无法确定您正在查看的代码是否真的需要以这种方式编写。
我正在尝试解构另一个编码员编写的方法以查看它是如何工作的,但它有点令人困惑
我们有一个将 Action 作为参数的委托。
private delegate void FunctionDelegate(Action next);
然后在构造函数中调用一个函数,该函数将这些委托的数组作为参数并执行数组中的每个值
LoadInSeries(LoadRoleAreaHours, LoadTableData);
函数看起来像这样
private void LoadInSeries(params FunctionDelegate[] _delegates)
{
var Delegates = new List<FunctionDelegate>(_delegates);
Func<Action, Action> creator = null;
creator = delegate(Action inner)
{
if (Delegates.Count > 0)
{
FunctionDelegate L = Delegates.First();
Delegates.RemoveAt(0);
Action next = delegate { L(inner); };
return creator(next);
}
else return inner;
};
Action outer = creator(null);
if (outer != null)
outer();
}
目的是将一系列函数链接起来,每个函数调用下一个函数,但使用多播委托并将每个函数添加到调用列表中不是很容易吗。
这段代码有什么不同吗?
没有好的Minimal, Complete, and Verifiable code example,就不可能完全理解代码。最值得关注的是您的代码示例包含一个神秘的 L()
方法,我们不知道其行为。 FunctionDelegate = Delegates.First();
语句也有问题。充其量,FunctionDelegate
标识符指的是 class 字段或 属性;在最坏的情况下,该语句甚至不会编译。无论哪种方式,都没有证据表明从输入列表中删除的委托对象实际上曾被调用过。
所以即使要回答这个问题,也必须做出一些基本假设,这些假设可能正确也可能不正确。
也就是说,在最好的情况下——代码在 L()
方法中隐藏了一些可怕的、复杂的机制,最终能够为当前调用调用委托creator
委托 — 您正在查看的代码并非像 MulticastDelegate
那样简单地按顺序调用委托。相反,代码构建了对 L()
方法的调用链,将每个委托实例按顺序传递给该方法。
由于您没有向我们展示 L()
方法,因此无法说明 代码实际做了什么。我同意,如果 L()
所做的只是调用您传递给它的委托,那么这段代码看起来像是一种非常复杂的方法来调用一组委托。但是,让编写代码的人从怀疑中获益,这仅仅意味着 L()
可能做了一些事情,而不是简单地调用委托。
当然,代码的作者可能不值得怀疑。在那种情况下,不仅使用多播委托会更简单,而且 最简单 实现只会遍历数组,以所需顺序调用每个委托。但是我这么说并没有真正了解代码的作用。我只是假设它打算对传递给它的委托做一些有用的事情。您发布的代码中没有证据支持这种慷慨的假设。
给我们完整的图片,可以提供更明确的答案。如果不知道 L()
是什么,或者传递的委托的目标方法中可能存在哪些副作用,则无法确定您正在查看的代码是否真的需要以这种方式编写。