如何防止递归

0 c# recursion

给定名为 的类OrderInfo,确保其他开发人员(包括我自己)不会意外地出现此处所示的递归错误的最佳方法是什么:

public class OrderInfo : ICollection<UnitModule> {

  // Other code for class...

  public bool Changed { get; private set; }

  public void Save() {
    Save(this); // I want the static method to handle saving the data
  }

  public static void Save(OrderInfo item) {
    for (int i = 0; i < item.Count; i++) {
      if (item[i].Changed) {
        item[i].Save();
      }
    }
    if (item.Changed) {
      item.Save(); // this would be bad!
      // Instead, all of the other developers should have to call the
      // Database Save method.
      // Is there a way to ensure this happens or do I have to rely on
      // everyone remembering this?
    }
  }

}
Run Code Online (Sandbox Code Playgroud)

编辑:使用标记的答案,我可以按如下方式编写我的类(为什么不重要 - 这只是防止递归):

public class OrderInfo : ICollection<UnitModule> {
  // Other code for class...
  bool saving; // <= new variable
  public bool Changed { get; private set; }

  public void Save() {
    if (!saving) {
      Save(this);
    } else {
      throw new Exception("This item is already being saved.");
    }
  }

  public static void Save(OrderInfo item) {
    item.saving = true;
    try {
      for (int i = 0; i < item.Count; i++) {
        if (item[i].Changed) {
          item[i].Save();
        }
      }
      if (item.Changed) {
        // item.Save(); <= NOTE: this would throw an exception
        DataAccess.Save(item);
        item.Changed = false;
      }
    } finally {
      item.saving = false;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*ley 5

通常,超出堆栈限制时发生的崩溃可作为出现问题的警告。只要代码在投入生产之前经过粗略的测试,就会有人发现这个错误。