Why can't we define a variable inside an if statement?

前端 未结 5 1043
余生分开走
余生分开走 2020-12-01 04:13

Maybe this question has been answered before, but the word if occurs so often it\'s hard to find it.

The example doesn\'t make sense (the expression is

相关标签:
5条回答
  • 2020-12-01 04:41

    This has to do with the difference between a statement, and an expression. An expression has a value, whereas a statement does not.

    Using your examples, notice these classifications:

    StringBuilder sb; // statement
    
    sb = new StringBuilder("test") // expression
    
    StringBuilder sb = new StringBuilder("test"); // statement
    

    Notice that only the middle portion is a expression.

    Now we move onto your conditional statement. The syntax for using the not-equals operator is

    expression != expression
    

    So on both sides of the != you need something that actually has a value (this just makes sense). Ergo, you cannot have statements on either side of the operator. This is why the one version of your code works, while the other does not.

    0 讨论(0)
  • 2020-12-01 04:43

    This is because section 8.5.1 of the C# language spec. states:

    Furthermore, a variable initializer in a local variable declaration corresponds exactly to an assignment statement that is inserted immediately after the declaration.

    This basically means that, when you do:

    StringBuilder sb = new StringBuilder("test")
    

    You're, in effect, doing the exact same thing as:

    StringBuilder sb; sb = new StringBuilder("test")
    

    As such, there is no longer a return value for your check against != null, as the assignment isn't a single expression, but rather a statement, which is a local-variable-declarator comprised of an identifier followed by an expression.

    The language specification gives this example, stating that this:

    void F() {
       int x = 1, y, z = x * 2;
    }
    

    Is exactly equivalent to:

    void F() {
       int x; x = 1;
       int y;
       int z; z = x * 2;
    }
    
    0 讨论(0)
  • 2020-12-01 04:46

    Try C#7's Pattern Matching.

    Using your example:

    if (new StringBuilder("test") is var sb && sb != null) {
        Console.WriteLine(sb);
    }
    
    0 讨论(0)
  • 2020-12-01 04:49

    Instead of:

    if ((StringBuilder sb = new StringBuilder("test")) != null) {
        Console.WriteLine(sb);
    }
    

    One could also write:

    for (StringBuilder sb = new StringBuilder("test"); sb != null; sb = null) {
        Console.WriteLine(sb);
    }
    

    This for loop will execute once if your variable it not null. At the end of the loop, your temporary variable is set to null. The loop condition then evaluates to false, and the next statement continues after the closing brace is executed. Exactly as your if statement originally intended.

    0 讨论(0)
  • 2020-12-01 05:01

    C# 7.0 introduced ability to declare out variables right inside conditions. In combination with generics, this can be leveraged for the requested result:

    public static bool make<T> (out T result) where T : new() {
        result = new T();
        return true;
    }
    // ... and later:
    if (otherCondition && make<StringBuilder>(out var sb)) {
        sb.Append("hello!");
        // ...
    }
    

    You can also avoid generics and opt for a helper method instead:

    public static bool makeStringBuilder(out StringBuilder result, string init) {
        result = new StringBuilder(init);
        return true;
    }
    // ... and later:
    if (otherCondition && makeStringBuilder(out var sb, "hi!")) {
        sb.Append("hello!");
        // ...
    }
    
    0 讨论(0)
提交回复
热议问题