问题描述
只是为了获得一些乐趣而编写代码并让我了解匿名方法等。我有一个类,其主要目的是在循环中运行 lambda。 lambda 有一个 out 参数(exit),它被传递回类。现在我可以按照下面的代码嵌套这些,其中 l2 在 l1 的 lambda 中声明。
int outer = 0;
Loop l1 = new Loop().Infinite((out bool outerExit) =>
{
int inner = 0;
outer++;
Loop l2 = new Loop().Infinite((out bool innerExit) =>
{
inner++;
Debug.WriteLine($"{outer}-{inner}");
innerExit = inner >= 3;
outerExit = inner >= 3;
});
//outerExit = outer >= 3;
});
Assert.Equal(3,outer);
然而,这会在 l2 lambda 中出现错误,我将值分配给外层出口。
错误 CS1628 不能使用 ref、out 或 in 参数 'outerExit' inside 匿名方法、lambda 表达式、查询表达式或本地 功能
这个想法是在满足特定条件时从内部循环中退出两个循环。
感兴趣的人。
public class Loop
{
//this is a delegate TYPE!!! that matches our function
public delegate void ExitableAction<T1>(out T1 a);
//in thiscase it is a bool
protected ExitableAction<bool> action;
protected LoopType type;
public Loop Infinite(ExitableAction<bool> actn)
{
action = actn;
type = LoopType.Infinite;
Start();
return this;
}
protected void Start()
{
bool exit = false;
while(!exit)
{
action.Invoke(out exit);
}
}
}
解决方法
关于为什么不能使用 ref
/out
参数,请参阅 this post。
您似乎想要重新创建具有“中断”功能的“循环”语句。您可以使用另一个 out
委托代替使用 break
参数来实现 Action<bool>
语句。
public class Loop
{
protected Action<Action<bool>> action;
public Loop Infinite(Action<Action<bool>> actn)
{
action = actn;
Start();
return this;
}
protected void Start()
{
bool exit = false;
while (!exit)
{
// passes the Action<bool> that assigns the given bool to exit
action((b) => exit = b);
}
}
}
int outer = 0;
Loop l1 = new Loop().Infinite(setOuterExit =>
{
int inner = 0;
outer++;
Loop l2 = new Loop().Infinite(setInnerExit =>
{
inner++;
Console.WriteLine($"{outer}-{inner}");
setInnerExit(inner >= 3);
setOuterExit(inner >= 3);
});
setOuterExit(outer >= 3);
});
这给出了最终的 outer
值 3。但是如果你想要那个,你可以删除内部循环中的 setOuterExit
调用 - 它也给出 3 作为输出。
现在,由内部 exit
调用分配给 setOuterExit
的值正在被外部 setOuterExit
调用“覆盖”,因此外部循环在命中时不会立即中断内部 setOuterExit
。我们可以将 exit
的分配更改为:
action((b) => exit |= b);
这样,如果 exit
曾经设置为 true
,则没有其他值可以覆盖它。这将解决这个问题,但请注意,setOuterExit
仍然不会像真正的 break;
语句那样工作。例如,setOuterExit
之后的代码仍然会被执行。