我有一个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.IsValid
被false
PopulateErrorData()
设置为Model.method(data)
,它仍然没有让我离开循环?
答案 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
的唯一时间是实际将参数分配给。