如何从代码块中引用C#委托

本文关键字:引用 委托 代码 | 更新日期: 2023-09-27 18:21:53

我正在开发一个大量使用委托的程序。为了简单起见,我们假设我有以下类:

class ProcContainer<T>
{
    public delegate T Proc(ProcContainer<T> parentContainer); // my delegate type
    public Proc Content; // a field in the class in which a Proc "instance" is stored
}

换句话说:Proc是一个接受ProcContainer作为其(唯一)参数的委托类型。ProcContainer在其Content字段中包含一个Proc"实例"。

现在我想创建一个这样的委托:

T someVal = new T();
ProcContainer<T>.Proc proc = delegate(ProcContainer<T> parentContainer)
{
    parentContainer.Content = <<<this_delegate>>>;
    return someVal;
};

再说一遍,我想创建一个接受ProcContainerProc实例,该实例将ProcContainer的内容设置为手头的Proc

因此,如果调用了我的Proc,它应该用自己覆盖所提供的ProcContainer的当前内容。

问题:我能在C#中做到这一点吗?如果是:如何?

如何从代码块中引用C#委托

<<<this_delegate>>>等于proc,但您必须稍微调整代码以使其编译(并逻辑工作)。

ProcContainer<T>.Proc proc = null;
proc = delegate(ProcContainer<T> parentContainer)
{
    parentContainer.Content = proc;
    return someVal;
};

我注意到您有一个解决方案,但没有解释为什么原始代码会产生错误。简洁地生成一个调用自己的匿名函数是很棘手的。

如果包含委托实例的变量是本地变量,那么在其自己的初始化中使用本地变量的尝试通常被标记为在已知写入本地变量之前读取该变量的尝试。

如果包含委托实例的变量是实例字段,则在其自身初始化中使用该字段的尝试通常被标记为在字段初始化器中使用this,这是非法的。(这是非法的,因为这是错误的常见原因;字段初始值设定项中的this指的是构造函数尚未运行的对象,如果取消引用它,可能会导致各种错误。)

现在,您可能会合理地注意到,在第一种情况下,变量通常只是"提到",而不是实际的"读取"。在第二种情况下,"this"也没有被取消引用。语言设计团队决定简单地使规则普遍适用,而不是创建一个特殊规则来软化未被拒绝的匿名函数中出现的违规行为。尽管这有点烦人,但没有特殊情况需要在文档中进行设计、指定、实现、测试,然后进行解释。

我注意到,制作一个匿名函数来调用自己而不在单独的步骤中对变量进行赋值并不容易。这并非不可能。您可以通过巧妙地使用Y组合子进行匿名递归来做到这一点。但这样做会使代码变得足够难阅读,以至于大多数人不会认为这是一个好的解决方案。