【问题标题】:Passing a Delegate[] to a method将 Delegate[] 传递给方法
【发布时间】:2016-08-11 07:00:24
【问题描述】:

我正在尝试解构另一个编码员编写的方法,以查看它是如何工作的,但它变得有点混乱

我们有一个将 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();
        }

意图过于链接一系列函数,每个函数调用下一个函数,但使用多播委托并将每个函数添加到调用列表中并不容易。

这段代码有什么不同吗?

【问题讨论】:

  • 这真的有效吗?如果是这样,它仍然只是模拟多播委托的一种不必要的复杂和昂贵的方式。此外,尽量避免函数式代码中的变异状态——这是很难找到和修复的错误的重要来源。哎呀,即使是对代表的简单迭代也会比你现在拥有的更好。并且不要忘记您可以对匿名函数使用 lambda 语法 - inner =&gt; { ... } 而不是 delegate(Action inner) { ... }
  • @Luaan 它可以工作,但它所做的只是调用一系列函数,我们通常通过创建一个函数来调用这些方法。

标签: c# lambda delegates anonymous-function


【解决方案1】:

没有好的Minimal, Complete, and Verifiable code example,就不可能完全理解代码。最重要的问题是您的代码示例包含一个神秘的L() 方法,我们不知道它的行为。 FunctionDelegate = Delegates.First(); 语句也存在问题。充其量,FunctionDelegate 标识符指的是类字段或属性;在最坏的情况下,该语句甚至不会编译。无论哪种方式,都没有证据表明从输入列表中删除的委托对象实际上被调用过。

因此,即使要回答这个问题,也必须做出一些基本假设,这些假设可能正确,也可能不正确。

也就是说,在最好的情况下——代码在 L() 方法中隐藏了一些可怕的、令人费解的机制,最终能够为当前调用 creator 委托而调用委托— 您正在查看的代码不仅仅是按顺序调用委托,就像MulticastDelegate 的情况一样。相反,代码正在构造一个对L() 方法的调用链,将每个委托实例按顺序传递给该方法。

由于您没有向我们展示L() 方法,因此无法说明代码实际上做了什么。我同意,如果 L() 所做的只是调用您传递给它的委托,那么这段代码看起来是一种非常复杂的方式来调用委托数组。但是,让编写代码的人受益,这仅仅意味着L() 可能会做一些事情,而不是简单地调用委托。

当然,代码的作者可能不值得怀疑。在这种情况下,不仅只使用多播委托会更简单,最简单 实现将只遍历数组,以所需的顺序调用每个委托。但我这么说是在不知道代码做了什么的情况下说的。我只是假设它打算对传递给它的代表做一些有用的事情。您发布的代码中没有任何证据支持这种慷慨的假设。

给我们全貌,可以提供更明确的答案。在不知道L() 是什么,或者传入的委托的目标方法中可能存在什么副作用的情况下,无法确定您正在查看的代码是否真的需要这样编写。

【讨论】:

  • 我的错,我错过了一些文本 L 实际上是 FunctionDelegate 的一个实例,它的值是通过调用 Delegates.First() 在每次迭代中分配的。我会相应地更新代码。
  • 为了提供更多信息,我们需要调用 5 个函数来设置我们的数据。编码器为每个函数添加了一个(Action next)作为参数,以使签名与FunctionDelegate相同。 4 个函数是 All theSilvellight 中的异步函数,最后一个是一个事件处理程序,用于告知数据已加载。每个函数使用 next 参数在其回调方法中调用下一个函数。尽管这些函数无论如何都没有链接,并且可以按任何顺序调用。他们也不必等待任何其他功能完成即可开始执行。
  • @Abhi:这些方法是什么样的。没有看到它们,仍然不可能完全理解代码。如果他们总是只在自己执行的开始或结束时调用next,那么我仍然会说这段代码毫无意义。如果每个回调方法在它自己的执行过程中选择在哪里调用next,实际上它们有时会在它们自己的执行过程中调用next——即它们做一些工作,调用next,然后做一些更多的工作——那么也许有一些意义。但是,如果没有全貌,就不可能说。
猜你喜欢
  • 2018-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-04
  • 2011-01-01
  • 2021-04-25
  • 2014-06-03
相关资源
最近更新 更多