15

C#: When to Use 'when'

 5 years ago
source link: https://www.tuicool.com/articles/hit/3EZ7viZ
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

C# 6 introduced the when keyword. The  when keyword is a way to filter an exception in a catch block by some specific criteria. It was later extended to case statements in C# 7. I'll focus on when to use it in exceptions in this post and address its use in a case statement in another post.

Catch Without When

Let's say you want to handle the same type of exceptions using different criteria. A common scenario for this is an HttpException. When you catch an HttpException, the response code is available on the ResponseCode property. Depending on the response code, you may want to take different actions.

try
{
 // do web call 
}
catch(HttpException ex)
{
  if(ex.WebEventCode >= 500)
  {
    HandleServerError(ex);
  }
  else if(ex.WebEventCode >= 400)
  {
    HandleNotFoundError(ex);
  }
  ...

}

As you can see, handling the error involves a series of if statements within the catch block. It's not the most elegant looking code. The nested blocks make it more difficult to read, which makes it easier to introduce defects.

Catch When

Enter the when keyword. Let's look at that same logic using this keyword.

try
{
 // do web call 
}
catch(HttpException ex) when (ex.WebEventCode >= 500)
{
  HandleServerError(ex);
}
catch(HttpException ex) when (ex.WebEventCode >= 400)
{
  HandleNotFoundError(ex);
}

Appying when to the same code reduces nesting. It's intuitive, so it makes the catch blocks easier to understand.

At the time of writing this article, the when keyword isn't formatted as a keyword in the code styler. I'll take this as evidence that it isn't widely known. It's unfortunate since it's so useful in so many scenarios!

Going Beyond the Exception

It's possible to evaluate more than just the exception in the <code>when</code> statement. Doing so is actually quite useful. Take a look at the following example:

public void DoRecursion(int recurseCount = 3)
{
  try
  {
    throw new Exception("recurse until 0");
  }
  catch(Exception e) when (recurseCount > 3 && e.Message == "recurse until 0")
  {
    DoRecursion(recurseCount--);
  }
}

As you can see, it's useful to evaluate other variables besides the caught exception. In fact, I used this today to implement a backoff for a web call to an API.

Conclusion

You should start using the when keyword in scenarios where you have to inspect the exception to make a decision. I wouldn't worry too much about other developers not familiar with this keyword. It's so intuitive, that they'll pick it up quickly! If they don't pick up on it, you can direct them here for an intro or to the official documentation for complete coverage. But, do be careful about object reference exceptions in your  when expression. You wouldn't want to throw anew!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK