Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can the new is pattern match syntax work with existing variables?

I have existing code:

    internal bool firstAsSymbol(out Symbol s)
    {
        return (s = first as Symbol) != null;
    }

I can use the new is syntax, but I need to introduce local variables:

    internal bool firstAsSymbol(out Symbol s)
    {
        var result = first is Symbol sym;
        s = sym;
        return result;
    }

EDIT: In fact, the above code doesn't compile! sym may be undefined on the s = sym; line. So it's even worse: you have to use an if statement and assign s in both the then and else clause. (It does try to allow sym to be valid to touch in the right clause).

Is there any simpler alternative (other than the original code, of course)?

like image 624
Mark Hurd Avatar asked Jan 10 '17 12:01

Mark Hurd


1 Answers

As you have discovered, variables introduced via an is T expression end up in scope after the expression line, but are unusable as they may not be assigned.

The reasons behind this are due to the new out var feature. To make that feature work the way they wanted, the language team have allowed out var variables to leak out into surrounding scope. They then made the decision to allow is T variables to leak in the same way, even though they can't be used in that outer scope, as they may not be assigned.

I wrote an article on this sorry state of affairs recently: C# 7, “out var” and changing variable scope.

As for how you could rewrite the code to take advantage of C# 7 features, one way is to use a tuple:

internal (bool, Symbol) FirstAsSymbol() =>
    first is Symbol sym ? (true, sym) : (false, null);

But really, it would be worth looking at the code that calls FirstAsSymbol to see whether that could make better use of the new features.

like image 172
David Arno Avatar answered Oct 12 '22 13:10

David Arno