-1

I noticed that ReSharper suggests the following syntax in C# code. Old:

if (wizardStep !=null && wizardStep.progressId > 0)

New:

if (wizardStep is {progressId: > 0})

It works well, and I like it - looks cleaner than original. But for the life of me, I can't find any documentation about this syntax. What is possible, what are limitations, etc. And googling for is is not very helpful. Microsoft C# documentation doesn't mention anything of the kind!

I realize, this question stretches SO rules a little, I am not asking for an opinion. Maybe proof that this code is legal.

UPDATE: Don't know who closed this question - but it has nothing in common with the one that it is linked to! This is about Relational Pattern in C# 9; that one about is syntax in C# 8.

Felix
  • 9,248
  • 10
  • 57
  • 89
  • 3
    It's using both a [Property Pattern](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#property-patterns) and a [Relational Pattern](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-9#pattern-matching-enhancements) (on the property). – madreflection Apr 14 '21 at 19:02
  • 3
    Yes, this code is legal and is part of the new "pattern matching" movement in C#. https://learn.microsoft.com/en-us/dotnet/csharp/pattern-matching and https://learn.microsoft.com/en-us/archive/msdn-magazine/2019/may/csharp-8-0-pattern-matching-in-csharp-8-0, specifically the construct you see here is a "property pattern" https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#property-patterns – Lasse V. Karlsen Apr 14 '21 at 19:02
  • Thank you! I saw pattern matching (although I didn't see MSDN Magazine article before; very helpful addition) - and I can make a mental leap from `Positional Pattern` to anonymous type... But the *condition* in the object definition is what baffles me. – Felix Apr 14 '21 at 19:16
  • 1
    That's the Relational Pattern part. You can now do things like `if (x is (> 0 and < 10))`... the part after `is` is a conjunctive pattern of two relational patterns, and I used superfluous parentheses there to give a better idea of how it works. – madreflection Apr 14 '21 at 19:18
  • Something like `is {progressId: 0}` is a constant pattern on the property. `0` is the constant. So now `> 0` is a relational pattern in its place. – madreflection Apr 14 '21 at 19:20
  • _"it has nothing in common with the one that it is linked to"_ -- uh. "Nothing"? Hardly. The "relational" pattern you describe is simply a subset of the broader "property pattern" feature. It's all documented in the same place, i.e. the language reference where you should have asked in the first place. That's hardly "nothing in common", and indeed any reasonable person would see that they are actually _the same_. – Peter Duniho Apr 15 '21 at 00:13
  • And it looks like a number of valuable comments have been deleted... Oh, well - at least I got an answer that I couldn't get anywhere else – Felix Apr 16 '21 at 01:32

1 Answers1

1

What ReSharper is suggesting is a combination of pattern matching features, one of which is new in C# 9.0.

{ progressId: ... } is a Property Pattern, that tests the progressId property. It's one of the recursive patterns, meaning that other patterns can be nested within it.

Prior to C# 9.0, there's little you could do with an int property in a property pattern. You might nest a constant pattern like 0, i.e. { progressId: 0 }, to test that progressId is equal to 0.

C# 9.0 introduces several new kinds of patterns. ReSharper is suggesting that you use one of those, a Relational Pattern, for the range test on that property.

Pattern matching is an alternative way of expressing tests. You said you liked it so that's great; some people might not. The IL code that it generates will be the same, so it'll be entirely a matter of preference. I compiled the pattern matching version that ReSharper suggested and ILSpy decompiled it to exactly what you originally had.


To address one of the comments: The { ... } part looks like an anonymous type because it isn't preceded by a type name, but without the new keyword, it's not an anonymous type. It's just a pattern, a syntax for expressing tests that get translated to the more fundamental tests that you would see without pattern matching. It has no type, unlike the expression being tested.

madreflection
  • 4,744
  • 3
  • 19
  • 29