即使条件不再满足,while循环也不会停止

时间:2018-03-23 20:49:27

标签: c#

我有一个do while循环,其条件取决于对象的属性值。该对象如下所示:

public class MyObjectType
{
   public int Id { get; set; }
   public bool IsValid { get; set; }
   public DateTime CompletionTimeStamp { get; set; }
   public string Comments { get; set; }
}

do while循环如下所示:

public Task DoSomething(MyObjectType myObject)
{
   do
   {
      // Call DB get some values
      var someData = _myRepository.Get(myObject.Id);

      // Process data
      someData.SomeValue = SomeFunction(someData.Property1, someData.Property2);

      // Not pretty code but I'm trying to set a few values for myObject here
      if(someData.SomeValue == null)
         MyUtils.PopulateErrorData(ref myObject, "Something went wrong!!!");

      // Save data -- When there's an error, I don't want to this this step
      await _myRepository.Save(someData);
   }
   while(myObject.IsValid);
}

PopulateErrorData()函数只是我设置myObject的值的地方:

public static void PopulateErrorData(ref MyObjectType myObject, string comments)
{
    myObject.IsValid = false;
    myObject.CompletionTimeStamp = DateTime.UtcNow;
    myObject.Comments = comments;
}

我不能说我对这种方法感到非常高兴,但在我的DoSomething()函数中,这是一个后端维护功能,我需要经过很多步骤,如果有的话他们失败了,我想中止这个过程。

我想我可以使用do while并且当条件不再满足时,无论如何它都会让我离开循环但是它不是。它一直在继续。在上面的代码中,如果someData.SomeValue == null,我永远不应该保存数据,但正如我所说,代码仍在继续,我最终将数据保存在数据库中。

知道为什么即使myObject.IsValidfalse PopulateErrorData()设置为Model.method(data),它仍然没有让我离开循环?

3 个答案:

答案 0 :(得分:4)

在您的代码中,您首先保存数据,然后检查IsValid属性。只需使代码更简单:

public Task DoSomething(MyObjectType myObject)
{
   // if myObject.IsValid is set initially, then uncomment the following line.
   // myObject.IsValid = true;
   while(myObject.IsValid)
   {
      // Call DB get some values
      var someData = _myRepository.Get(myObject.Id);

      // Process data
      someData.SomeValue = SomeFunction(someData.Property1, someData.Property2);

      // Not pretty code but I'm trying to set a few values for myObject here
      if(someData.SomeValue == null)
         MyUtils.PopulateErrorData(ref myObject, "Something went wrong!!!");

      if(!myObject.IsValid)
          break;

      // Save data -- When there's an error, I don't want to this this step
      await _myRepository.Save(someData);
   }

}

答案 1 :(得分:3)

认为你需要改变这个

  // Not pretty code but I'm trying to set a few values for myObject here
  if(someData.SomeValue == null)
     MyUtils.PopulateErrorData(ref myObject, "Something went wrong!!!");

  // Save data -- When there's an error, I don't want to this this step
  await _myRepository.Save(someData);

到此

  if(someData.SomeValue == null)
  {
     MyUtils.PopulateErrorData(ref myObject, "Something went wrong!!!");
  }
  else
  {
      // Save data -- When there's an error, I don't want to this this step
      await _myRepository.Save(someData);
  }

或者

  if(someData.SomeValue == null)
  {
     MyUtils.PopulateErrorData(ref myObject, "Something went wrong!!!");
     break;
  }
  // Save data -- When there's an error, I don't want to this this step
  await _myRepository.Save(someData);

虽然在我的生活中,我不明白在这种特殊情况下,while循环的目的是什么。

答案 2 :(得分:3)

其他upvoted答案显示您需要进行的更改,但我想确保您知道为什么就是这样(您似乎缺少一些C#基础知识)。

while循环的条件是连续评估。它仅在循环的开头(while)或结束(do ... while)进行评估。因此,设置标志不会阻止发生下一个语句。要提前退出循环,您需要break(完全退出循环)或continue(跳到下一次迭代)。

因此,解决方案是将保存放在else中,将break添加到现有if块,或执行else并完全删除循环,除非你真的想多次这样做。

您还有一个不必要的ref。 C#中的类已作为引用传递,因此同一对象的未来用户将看到对其属性的更改。您需要使用ref的唯一时间是实际将参数分配给

相关问题