我正在开发一个大量使用代理的程序。为简单起见,我们假设我有以下类:
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
在Proc
字段中包含Content
“实例”。
现在我想创建一个这样的委托:
T someVal = new T();
ProcContainer<T>.Proc proc = delegate(ProcContainer<T> parentContainer)
{
parentContainer.Content = <<<this_delegate>>>;
return someVal;
};
再说一遍,我要创建一个Proc
个实例,接受一个ProcContainer
,将ProcContainer
的内容设置为Proc
at {手。
因此,如果我的Proc
被调用,它应该用自己覆盖提供的ProcContainer
的当前内容。
问题:我可以用C#做到吗?如果是:如何?
答案 0 :(得分:1)
<<<this_delegate>>>
等于proc
,但您必须稍微调整一下代码才能使其编译(并在逻辑上工作)。
ProcContainer<T>.Proc proc = null;
proc = delegate(ProcContainer<T> parentContainer)
{
parentContainer.Content = proc;
return someVal;
};
答案 1 :(得分:1)
我注意到您有一个解决方案,但没有解释原始代码产生错误的原因。简明地创建一个自称的匿名函数是很棘手的。
如果包含委托实例的变量是本地的,那么在自己的初始化中尝试使用本地通常会被标记为在知道本地变量被写入之前尝试读取它。
如果包含委托实例的变量是实例字段,那么在字段初始化程序中通常会将尝试在其自己的初始化中使用该字段标记为this
,这是非法的。 (这是非法的,因为这是错误的常见原因;字段初始值设定项中的this
指的是其构造函数尚未运行的对象,如果您取消引用它,可能会导致各种错误。)
现在,你可能会合理地注意到,在第一种情况下,变量通常只是“提到”而实际上并不是“读”。在第二种情况下,“this”再次没有被解除引用。语言设计团队决定简单地使规则适用,而不是创建一个软化一般规则的特殊规则,如果违规出现在一个未被激活的匿名函数中。虽然这有点令人烦恼,但没有特殊情况需要设计,指定,实施,测试,然后在文档中进行解释。
我注意到,创建一个匿名函数并不是 easy ,而不需要在单独的步骤中对变量进行赋值。它不是不可能。您可以通过巧妙地使用Y组合器进行匿名递归来实现。但这样做会使代码难以阅读,大多数人都不会认为这是一个很好的解决方案。