是否可能有一个函数作为while条件
本文关键字:作为 while 条件 bool 有一个 函数 是否 | 更新日期: 2023-09-27 18:18:00
晚上好
我想知道我是否可以这样做:
while(true)
{
MyEnum currentValue = GetMyEnumValueFromDB();
if(currentValue == MyEnum.BreakIfYouGetThis)
break;
else if(currentValue == MyEnum.AlsoBreakIfYouGetThis)
break;
else
//Do some computing
}
但是不使用while(true)循环,我想将条件逻辑封装在Func中并像这样执行:
while(new Func<bool>(/* what goes here? */))
{
//Do some computing
}
至少在我的情况下,它会看起来更干净,但我不确定如何做到这一点(有点新在Func/Action..)。
EDIT希望这能澄清:
也可以这样做:
while(GetMyEnumValueFromDB() != MyEnum.BreakIfYouGetThis &&
GetMyEnumValueFromDB() != MyEnum.AlsoBreakIfYouGetThis)
{
//Do some computing
}
但是这是对数据库的2个调用…
谢谢=)
你可以有:
Func<bool> condition = ...;
while (condition())
{
}
你在想这个吗?我不太清楚……
编辑:在你给出的例子中,我会使用这样的内容:private static readonly MyEnum[] BreakEnumValues = {
MyEnum.BreakIfYouGetThis,
MyEnum.AlsoBreakIfYouGetThis
};
...
while (!BreakEnumValues.Contains(GetMyEnumValueFromDB()))
{
...
}
或:
private static bool ShouldBreak(MyEnum enumFromDatabase)
{
return enumFromDatabase == MyEnum.BreakIfYouGetThis ||
enumFromDatabase == MyEnum.AlsoBreakIfYouGetThis;
}
...
while (!ShouldBreak(GetMyEnumValueFromDB))
{
...
}
编辑:为了反驳keith的回答,这是完全有效的:
while (new Func<bool>(() => {
Console.WriteLine("Evaluating...");
return true;
})()) {
Console.WriteLine("In loop");
count++;
if (count == 5)
{
break;
}
}
这是可怕的,但它是有效的。(通过显式地调用Invoke
,可以使它稍微不那么可怕,但它仍然不太好。)
您可以这样做,但如果您没有令人信服的理由这样做(例如您将条件函数作为参数传递),我将直接将您的逻辑包装在函数中并直接调用它:
while(KeepGoing())
{
//Do stuff
}
bool KeepGoing()
{
// Check conditions for continuing
var value = GetMyEnumValueFromDB();
return value != MyEnum.BreakIfYouGetThis && value != MyEnum.AlsoBreakIfYouGetThis;
}
首先,在while循环中调用数据库是一个坏主意。提前查询需要的内容并相应地循环。
它似乎多态性可以在这里成为您的朋友。如果您需要保持相同的流,您可以这样做:
interface IWhileLoopContinuable
{
bool KeepGoing {get;}
void DoWork();
}
那么你可以在这个可枚举对象上使用TakeWhile
:
foreach(var item in queriedAsIWhileLoopContinuable.TakeWhile(c => c.KeepGoing))
{
item.DoWork();
}
话虽如此,您可以查询您想要的内容并进行处理
首先你不能"new"一个Func,就像你不能新建任何委托类型一样。你必须指定一个现有的命名方法或函数文字(又名匿名委托,lambda等)来初始化Func变量。
//these won't compile; Func has no constructor
Func<bool> condition = new Func<bool>();
//As Jon Skeet notes, these will compile because of language-provided syntax,
//even though Funcs have no constructor with a delegate parameter.
Func<bool> condition = new Func<bool>(SomeNamedMethodReturnsBool);
Func<bool> condition = new Func<bool>(()=>true);
//and these will compile because you're directly assigning the delegate
Func<bool> condition = SomeNamedMethodReturnsBool;
Func<bool> condition = ()=>true;
你实际上不能在c#中做你想做的事;匿名委托必须分配给变量或参数才能使用。它不能作为抽象意义上的"函数字面量"就地使用。
即使可以,我也不知道这种语句的用途。委托不会每次都重新实例化(编译器将匿名委托转换为包含类的命名私有函数,并使用mashup名称),但是您在调用堆栈上添加了一个层,只是为了计算可以直接放在while()语句括号中的常量表达式。匿名委托的主要用途是你可以在运行时交换lambdas,为了做到这一点,你必须有一个变量。