如果执行期间的变量值之一变为真,则退出 C# 函数执行

exiting C# function execution if one of the variable value during execution becomes true

我有一个函数 Parent() 和一个布尔值 Class 属性 手表,默认值为 true。 这个 fn Parent() 正在调用几个 Child 函数。 让我们假设在执行此函数或任何 child 函数期间 Watch 将其值更改为 false ,我希望执行停止并退出 Parent 函数。 Parent 返回无效。

这是单线程执行,没有使用异步和任务构造

您可以在不同的线程中执行每个 Child 函数,并在 Parent 函数中使用一个循环来监视 Watch 值,或者您可以在每次 Child 调用后检查 Watch 值。没有代码示例或更多信息,很难回答。

fn Parent()
{
    childfn();
    if( !Watch )
        return;

}

尽管让子函数 return bool 并检查它而不是使用 class 属性.

可能更好

这是一个演示模型,您可以如何构建它。 它演示了一个工作流程,其中 Child2 将变量设置为 false 并在此之后退出,因此从未执行过 Child3。

不过我建议让子函数 return 变成布尔值。您为单线程应用程序建议的设计似乎不是一个好的设计。

public class Test
{
    public bool Watch { get; set; }

    public Test()
    {
        this.Watch = true;
    }

    public void Parent()
    {
        this.Child1();
        if(this.Watch == false)
        {
            return;
        }
        this.Child2();
        if(this.Watch == false)
        {
            return;
        }
        this.Child3();
        if(this.Watch == false)
        {
            return;
        }
    }

    public void Child1()
    {
        //Do stuff
    }

    public void Child2()
    {
        this.Watch = false;
    }

    public void Child3()
    {
        //Do stuff
    }
}

我假设这是你的代码结构..如果我的假设是错误的请纠正我

我还有一个问题 - 所有的子函数都具有相同的签名?如果是这样,我会建议基于代表的方法。否则这里是一个简单的例子

bool Watch { get; set; }


    // Parent is control center, calling one child after another
    void Parent()
    {
        ChildOne(1);
        if (Watch == false)
            return;

        ChildTwo(1,3);
        if (Watch == false)
            return;
    }

   /// signature type 1
    void ChildOne(int a)
    {

    }

    /// signature type 2
    void ChildTwo(int a, int b)
    {
        Watch = false;
    }

编辑 1 这是如果所有函数都具有相同签名的方法

  class ChildFuntionExecutor
    {
        public Func<int,int> ChildFuntion;
        public int Operand1;
        public void Evaluate()
        {
             ChildFuntion(Operand1);
        }
    }

    bool Watch { get; set; }


    // Parent is control center, calling one child after another
    void Parent()
    {
        // register all child functions 
        List<ChildFuntionExecutor> childFuntionQueue = new List<ChildFuntionExecutor>();
        childFuntionQueue.Add(new ChildFuntionExecutor { Operand1 = 10, ChildFuntion = this.ChildOne });
        childFuntionQueue.Add(new ChildFuntionExecutor { Operand1 = 10, ChildFuntion = this.ChildOne });


        foreach (var item in childFuntionQueue)
        {
            item.Evaluate();
            if (Watch == false)
                return;
        }
    }

    /// signature type 1
    int ChildOne(int a)
    {
        return a * 10;
    }

    /// signature type 1
    int ChildTwo(int a)
    {
        Watch = false;
        return a * 10;
    }

我认为最简单的方法是为此使用异常:

public class TestClass
{

    public void ParentMethod()
    {
        try
        {
            ChildMethod1();
            ChildMethod2();
        }
        catch (InvalidStateException ise)
        {
            return;
        }
    }

    public void ChildMethod1()
    {
        //do stuff, and then if the "watch" is set to true:
        throw new InvalidStateException();
    }

    public void ChildMethod2()
    {
        //do stuff, and then if the "watch" is set to true:
        throw new InvalidStateException();
    }
}

public class InvalidStateException : Exception { }

这里我定义了一个新的异常InvalidStateExceptionChildMethodX 可以在它希望父方法停止执行时引发该异常。在父方法中,你 try/catch 所有的子调用,当一个抛出时,它停止执行并跳到捕获中。

注意:异常的发生是因为发生了一些异常的事情。如果您认为这是正常的逻辑流程,那么我会恳请您尝试一些避免异常的方法。例外是昂贵的性能明智的。例如,在不使用异常的情况下,您可以执行以下操作:

public class TestClass
{
    public bool Watch { get; set; }

    public void ParentMethod()
    {
        Func<bool> c1Call = () => { Child1Method(); return Watch; };
        Func<bool> c2Call = () => { ChildMethod2(); return Watch; };

        if (c1Call())
            return;

        if (c2Call())
            return;
    }

    public void Child1Method()
    {
        //Do something, then this happens:
        Watch = true;
    }

    public void ChildMethod2()
    {
        //Do something, then maybe this happens:
        Watch = true;
    }
}

您可以在其中修改 Func<> 代表以接受任意数量的参数。给这只猫换皮的方法有十几种,但几乎所有方法都涉及在调用函数后检查标志以确定是否要退出。如果函数 return void,请考虑将它们更改为 return bool,这样您就可以执行以下操作:

if (ChildMethod1()) return;

非常简洁。否则,您可以使用 lambda 和委托的奇怪组合,但是当您开始使用它时,您必须问问自己,避免输入一些额外的 "if" 语句是否值得代码可维护性的损失?