如何访问和创建if语句变量C#

时间:2016-06-08 09:41:01

标签: c# if-statement

我正在尝试遵循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

4 个答案:

答案 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语句,您已经知道footrue,那么使用作用域本地有什么用?

关于你的第一个问题,我只是推迟整个方法。您基本上使用基于由两个或多个条件组成的布尔表达式的if语句。然后,一旦进入if语句,您就可以辨别出满足什么布尔条件。此外,您可能会遇到未初始化的变量,因为check1无法保证运行。

我完全重写了这一点并绕过了任何本地范围变量的需要:

  1. 每项条件的工作都是独立的:

    if (foo)
    {
        //whatever
    }
    else if (bar)
    {
        //whatever
    }
    
  2. 两种情况都有共同的工作:

    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.
});

这将限制这些临时值的范围。但是,这不会检查您是否以正确的方式实际使用checksvariables。如果出现问题然后简单的if语句就会更难调试。

这也可以扩展为接受Func而不是ActionIf方法也可以return结果。甚至可以使用ElseIf方法添加ElseIf方法(以模仿所有if语句行为)。