通过调用另一个方法退出方法

5

我想通过调用另一个方法来退出方法或函数的执行。到目前为止,我只发现了使用else的问题,并没有像我需要的那样。

示例如下:

public static void SomeMethod() {
    // some code
    ExitMethod();
    // the next line of code will never be executed
    Console.WriteLine("Test");
}

private static void ExitMethod() {
    // if possible the execution of the Method above will be stopped here
}
ExitMethod的作用类似于return语句,但由于它是一个方法,因此我可以更容易地添加if或其他条件。如果我经常在我的汇编程序中使用ExitMethod,我可以轻松地重构调用方法停止执行的条件。
例如,在明显不安全的尝试中保护dll时,可以使用这种方法,以便它需要一个序列号,只有在给定正确的序列号时,才会启用一些静态布尔值,然后在每次从dll调用函数时检查该值。
提前感谢您的帮助 :)
编辑: 通过使用可以为取消任务调用的另一个方法,我想避免像这样的情况:
public static void SomeMethod() {
    if (ExitMethod) return;
}

目标是只需调用 ExitMethod 方法,该方法会处理一切。

2
很抱歉,我不明白... 为什么你不想使用if语句? - StarterPack
3
ExitMethod() 中抛出异常怎么样?或者你可以让 ExitMethod 返回一个 bool,然后像这样使用它:if (ExitMethod()) return; - René Vogt
1
我认为你应该重新考虑这种方法。如果你不想要一个返回值,那么就不要有一个,这并不是必需的。但是,如果你想采用这种方法在ExitMethod中添加条件逻辑,那么你还必须在SomeMethod(以及所有调用ExitMethod的其他方法)中添加条件逻辑,以便你想要跳过的代码在某些情况下被跳过而在其他情况下不被跳过。这会导致设计混乱,增加代码量,而且有更直接的路径可走。最好应用你的条件并返回true或false,然后从那里进行处理。 - GrayFox374
1
你的想法是正确的,像这样使用异常来控制流程并不完全合适。但实际上,最正确的方法是从ExitMethod返回某些内容,并用if(..) return;包装调用。 - James Thorpe
1
你显然很沮丧。所以我再试一次重新表达我的问题... 为什么你要避免使用IF语句呢?在我看来,你可以通过使用IF语句来验证序列号并退出,而不需要跳过这些障碍。那么为什么要费尽心思避免使用IF呢?如果这个问题对你来说还是不清楚,我很抱歉。 - DeadZone
显示剩余13条评论
1个回答

5

从问题的评论中:

为什么没有更好的解决方案……?

隐式流控通常被认为是一种反模式——甚至有人反对异常的存在。一些特意不包含任何形式隐式流控的语言也存在(例如Go)。

以下是几种可用的方法。

显式流控

public bool ExitMethod() => // ...

public void SomeMethod()
{
  if (ExitMethod()) return;
  Console.WriteLine("Test");
}

没有文档注释,布尔返回值可能会令人困惑。使用枚举将导致自我记录的代码:
public enum ExitParentStatus : byte
{
  Continue, Return
}

public ExitParentStatus ExitMethod() => // ...

public void SomeMethod()
{
  if (ExitMethod() == ExitParentStatus.Return) return;
  Console.WriteLine("Test");
}

使用状态进行显式流程控制

public enum RequestStatus : byte
{
  Processing, Handled
}

public class Request
{
  public RequestStatus Status { get; set; }
}

public void ExitMethod(Request request) => // ...

public void SomeMethod(Request request)
{
  ExitMethod();
  if (request.Status == Handled) return;
  Console.WriteLine("Test");
}

使用yield return

这提供了其他开发人员正在接近设计不良代码的线索,稍微减少了出现错误的几率。

public void ExecuteConditionalCoroutine(IEnumerable<bool> coroutine)
{
  foreach (var result in coroutine)
  {
    if (result) return;
  }
}

public bool ExitMethod() => // ...

public IEnumerable<bool> SomeMethod()
{
  yield return ExitMethod();
  Console.WriteLine("Test");
}

ExecuteConditionalCoroutine(SomeMethod());

异常

如果你想让你的代码无法调试,请使用此方法。

public bool ExitMethod() { throw new ExitParentMethodException(); }

public void SomeMethod()
{
  try
  {
    ExitMethod();
    Console.WriteLine("Test");
  }
  catch (ExitParentMethodException) { }
}

后编译

使用类似于post-sharp的工具来自动注入代码分支。这是一种非常适用于难以维护代码的解决方案。

[ExitsParentMethod]
public bool ExitMethod() => // ...

public void SomeMethod()
{
  ExitMethod();
  Console.WriteLine("Test");
}

你有一些非常有趣的东西,但是根据我的了解和评论,这确实是一个非常稳定的解决方案。只需注意,异常可以在没有try的情况下处理。 - RememberOfLife

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接