我正在尝试遵循C#中的DRY原则,我想知道是否可以访问if
块中的参数检查。例如,以下是否可能?
if (foo == true || bar == false)
{
if (check0)
{
//foo is true
}
if (!check1)
{
//bar is false
}
}
我也想知道是否可以这样做,以保持范围清洁?:
if (var foo = runTimeAccessedVariable == "bar")
{
//we now have the runtime generated variable.
}
//but it doesn't exist here
答案 0 :(得分:4)
不,这是不可能的。实际上,由于您使用了短路||
运算符,因此甚至可能无法对第二次检查进行评估。
显然,你可以按照以下方式解决这个问题:
var fooIsTrue = (foo == true);
var barIsFalse = (bar == false);
if (fooIsTrue || barIsFalse)
{
...
}
请注意,这会更改代码的行为,因为始终会评估barIsFalse
。
答案 1 :(得分:2)
通过使用一对括号来定义新范围,可以轻松解决范围和重用问题;
pulic void MyFunc()
{
// do stuff here in the scope of MyFunc
{
// create child scope with new scoping rules and declare control variables
var fooTrue = foo == true;
var barFalse = bar== false;
if (fooTrue || barFalse)
{
if (fooTrue)
{
//foo is true
}
if (barFalse)
{
//bar is false
}
}
}
// stuff here cannot access fooTrue, barFalse.
}
这样就可以阻止变量泄漏出去'这部分功能。由于var barFalse
行不是快捷方式,因此存在一个小的语义差异,但从您的示例中可能看起来您可能无论如何都需要对其进行测试,因此它不应该成为一个问题。
答案 2 :(得分:0)
回答第二个问题,不能以这种方式声明变量。唯一类似的替代方法是使用{ }
创建自己的局部范围,并在if
语句之前声明局部变量:
{
bool foo;
if (foo = runTimeAccessedVariable == "bar")
{
}
}
无论如何,我不确定这种方法的好处是什么。如果您使用if
语句,您已经知道foo
是true
,那么使用作用域本地有什么用?
关于你的第一个问题,我只是推迟整个方法。您基本上使用基于由两个或多个条件组成的布尔表达式的if
语句。然后,一旦进入if
语句,您就可以辨别出满足什么布尔条件。此外,您可能会遇到未初始化的变量,因为check1
无法保证运行。
我完全重写了这一点并绕过了任何本地范围变量的需要:
每项条件的工作都是独立的:
if (foo)
{
//whatever
}
else if (bar)
{
//whatever
}
两种情况都有共同的工作:
if (foo)
{
//whatever
if (bar)
{
//whatever
}
}
两者在语义上都与你提议的相同。
答案 3 :(得分:0)
你实际上可以。你可以使用这样的(扩展)方法:
// For first case.
public static void If(this Lazy<bool>[] checks, Predicate<Lazy<bool>[]> ifCondition, Action<Lazy<bool>[]> ifAction) {
if (ifCondition(checks)) ifAction(checks);
}
// For second case.
public static void If(this object[] variables, Predicate<object[]> ifCondition, Action<object[]> ifAction) {
if (ifCondition(variables)) ifAction(variables);
}
使用它看起来像这样:
// First case.
new[] { new Lazy<bool>(() => foo == true), new Lazy<bool>(() => bar == false) }.
If(checks => checks[0].Value || checks[1].Value, checks => {
if (checks[0].Value) {
//foo is true
}
if (!checks[1].Value) {
//bar is false
}
});
// Second case.
new[] { "bar" }.If(variables => (string)variables[0] == "bar", variables => {
//we now have the runtime generated variable.
});
这将限制这些临时值的范围。但是,这不会检查您是否以正确的方式实际使用checks
或variables
。如果出现问题然后简单的if
语句就会更难调试。
这也可以扩展为接受Func
而不是Action
,If
方法也可以return
结果。甚至可以使用ElseIf
方法添加Else
和If
方法(以模仿所有if
语句行为)。