56

I see the following code sometimes, and have no idea what the expression is actually testing.

public static void Something(string[] value)
{
   if (value is { })
   {
      DoSomethingElse();
   }
}
Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
evan
  • 1,463
  • 1
  • 10
  • 13

2 Answers2

44

That's just the empty property pattern in C# 8, meaning the value not null. It matches any value type or reference type. As Panagiotis Kanavos notes in the comments, this is equivalent to the good old value is object check which has been in C# for a long time.

Generally if you were to specify a property, then it would match or not. This esoteric example illustrates that:

if (value is { Length: 2 })
{
   // matches any object that isn't `null` and has a property set to a length of 2
}

The property patterns work best and are most clear when comparing with other patterns in cases such as switch expressions.

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
  • 1
    what does mean empty object in this case? empty string, white space? – OlegI Feb 26 '20 at 15:21
  • it's quite crazy that `string s = "s"; if(s is { })` will return true – OlegI Feb 26 '20 at 15:31
  • 4
    @OlegI no it's not. `s` is definitelly not null. `is {}` is shorthand for `is object` and strings *can* be cast to object. – Panagiotis Kanavos Feb 26 '20 at 15:31
  • 6
    @OlegI how so? its a valid reference so it matches. – Daniel A. White Feb 26 '20 at 15:31
  • This type of expessions are called Recursive patterns and they can go really crazy (like `if (this is Box (var metadata, var _) { Label: "Books" } box) { ... }`.. See my example demo on [GitHub repo](https://github.com/PWrGitHub194238/Capgemini.NET/blob/master/CSharp80/15.RecursivePatterns/Program.cs). – Eatos Feb 26 '20 at 15:35
  • @Eatos good to note. i haven't written any yet but the toll collector example i saw looks amazong – Daniel A. White Feb 26 '20 at 15:39
  • 8
    Its a new world where structs can be null and references cannot be null, switch statements are reversed and various `!`, `!!`, `?` and `??` before and after properties mean different things. When will the syntactic sugar high end? – John Alexiou Feb 26 '20 at 15:59
  • 3
    Is it the same as `value != null`? – ca9163d9 Feb 27 '20 at 18:43
13

While Daniel's answer is right, I think it might be useful to add some context about why you may see the empty property pattern in use. Consider this example controller method that needs some validation done:

public async Task<IActionResult> Update(string id, ...) 
{
    if (ValidateId(id) is { } invalid)
        return invalid;
    ...
}

In the above, ValidateId() could return null or an instance of BadObjectRequestResult. If the former is returned, the validation is successful and moves on to the rest of the body of Update. If the latter is returned, is {} is true (i.e. of course an instance of BadObjectRequestResult is an object), and the validation fails.

Nicely, out of this we've also provided a variable name, invalid, which we can return immediately. Without that we'd need slightly more verbose code.

public async Task<IActionResult> Update(string id, ...) 
{
    var invalid = ValidateId(id);
    if (invalid != null)
        return invalid;
    ...
}

Whether one is more readable or the other is up to the reader, I've just presented one way the empty property pattern can be used.

Kit
  • 20,354
  • 4
  • 60
  • 103
  • In that case one should use `is object invalid`, not `is {} invalid` – Panagiotis Kanavos Feb 27 '20 at 08:34
  • 3
    @PanagiotisKanavos that would not work in this case because a return of `IActionResult` is required (well technically `Task`). If we go with your style, the `if` has the same result but `invalid` will be an `object` so this won't compile. – Kit Feb 27 '20 at 16:24