2015-11-14 17 views
0

我正在开发一个大量使用代表的程序。为简单起见,假设我有下面的类:如何从代码块中引用C#委托?

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; 
}; 

再次,把它变成文字:我想创建一个Proc实例接受ProcContainerProcContainer的内容设置到Proc在手边。

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

问题:我可以在C#中执行此操作吗?如果是的话:如何?

+2

declare'ProcContainer .Proc proc = null';在分配真实代码之前...'ProcContainer .Proc proc = null; proc =委托(......)' – Eser

回答

1

<<<this_delegate>>>等于proc但您必须调整一下代码以使其能够编译(并按逻辑工作)。

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

非常感谢。实际上,我想尝试一下,但最后我没有这样做,因为我通过'null'将隐藏在隐藏的委托助手类中,而不是实际的'Proc'实例。不过应该尝试过。嘿。 –

1

我注意到你有一个解决方案,但没有解释为什么原始代码会产生错误。简洁地制作一个自称的匿名函数是非常棘手的。

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

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

现在,你可能会合理地注意到,在第一种情况下,变量通常只是“提及”而不是实际“读取”。而在第二种情况下,“这个”再次不被解除引用。语言设计团队决定只是简单地适用这些规则,而不是制定一个特殊的规则来减轻违反一般规则的情况。虽然这有点麻烦,但没有特殊情况需要设计,指定,实施,测试,然后在文档中进行解释。

我注意到,它不是容易做一个匿名函数,它调用自己没有做一个单独的步骤分配给变量。这不是不可能。您可以通过巧妙地使用Y组合器进行匿名递归来做到这一点。但是这样做会使代码难以阅读,大多数人不会认为这是一个好的解决方案。