Hacker News new | past | comments | ask | show | jobs | submit login

The expression

    o is int i
is effectively:

    int i; // in the nearest enclosing scope
    (o is int && (i = (int)o)) // in place of an expression
The "fresh" variable `i` is available for use elsewhere. If an `i` already exists in that scope (the block the `if` statement is in), that is a redeclaration of a variable which is a compile-time error.

If the "is" expression evaluates to `false`, the variable `i` will not be assigned, however, it will still be declared. Attempting to use `i` if it is not definitely assigned is a compile-time error. However, you have the opportunity to re-assign it.

Some examples:

      if (!o is int i) throw Exception();
      use(i); // works: i is declared and always assigned

      if (o is int i) { do_something(i); }
      use(i); // compile-error: i declared but might not be assigned

      if (o is int i) { do_something(i); }
      else { i = 0; }
      use(i); // works -- definitely assigned
Thus the example pointed out in the post boils down to this in C# 6:

    int i;
    if (o is int) { 
      i = (int)o;
    } else {
      string s = o as string;
      if (s != null && !int.TryParse(s, out i)) {
        throw Exception();
    // i is definitely assigned here.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact