Pattern matching variable area

The Roslyn Pattern Matching Compliance Specification states that:

The scope of the template variable is as follows:

If the template appears in the condition of the if statement, its scope is a condition and a controlled statement of the if statement, but not its else clause.

However, the latest Microsoft β€œWhat's New” messages and presentations show this example:

public void PrintStars(object o) { if (o is null) return; // constant pattern "null" if (!(o is int i)) return; // type pattern "int i" WriteLine(new string('*', i)); } 

Displays a match for pattern i used outside the if matching region to which the pattern is mapped.

Is this surveillance or is the scope changed from the specification?

+6
source share
2 answers

I sent a similar question to Roslyn's problems and got an answer from DavidArno :

It's a long time, but you can read all the details about why the language the design team decided to "improve" the language in this way at # 12939 .

TL DR You are not alone in thinking that change is unintuitive and contrary to how the scope worked before. The team is sad anyway, and the change is here to stay.

It seems that a decision was made that this definition will be applied, so the specification is now outdated, and this definition, unfortunately, is here to stay:

Option 3: variable expressions are limited to blocks, for, foreach and using operators, as well as all built-in instructions:

This implies a built-in operator that is used as a nested operator in another expression - except inside the block. thus branches of the if statement, while body, foreach, etc. all will be considered embedded.

The consequence is that variables always avoid the condition if, but never its branches. As if you are putting thorns in all the places where you "should have".

Conclusion

While a little thin, we will take option 3. It hit Balance:

It allows you to use key scripts, including vars, for methods other than Try. as well as patterns and exits in if-statements bouncers. This does not lead to egregious and counterintuitive multi-level spills. This means that you will get more variables in the area than the current restrictive mode. This does not seem dangerous, as certain analysis of the assignments will prevent uninitialized use. However, this prevents the reuse of variable names and leads to more names showing in the completion lists. This seems like a reasonable compromise.

+3
source

From the same documentation:

variables entered by the template are similar to external variables described earlier

So actually this code:

 if (!(o is int i)) return; // type pattern "int i" 

More or less equal:

 int i; if (!(SomeParsingOn(o, out i))) return; // type pattern "int i" 

This means that i declared at the same level as if , which means that it is in the scope not only for if , but also for the following operators. That this is true may be seens when copying if :

 if (!(o is int i)) return; // type pattern "int i" if (!(o is int i)) return; // type pattern "int i" 

Gives error CS0128: A local variable with the name "i" is already defined in this area.

+3
source

Source: https://habr.com/ru/post/1012457/


All Articles