微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

输出变量和嵌套的 lambdas

如何解决输出变量和嵌套的 lambdas

只是为了获得一些乐趣而编写代码并让我了解匿名方法等。我有一个类,其主要目的是在循环中运行 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 之后的代码仍然会被执行。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。