Skip to content

Instantly share code, notes, and snippets.

@aienabled
Last active March 8, 2017 11:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aienabled/14797aee0c14b856b37526ec13aeae04 to your computer and use it in GitHub Desktop.
Save aienabled/14797aee0c14b856b37526ec13aeae04 to your computer and use it in GitHub Desktop.
C# 7.0 pattern matching rewriter for ReSharper (search and replace with pattern, automatic replace)

C# 7.0 brings many syntax improvements and features. One of the most valuable is the new pattern matching syntax. Usually it's used with switch blocks but it has another great use with if conditions. Currently there are no auto-replacement or auto-suggestion for that case in ReSharper yet (at current version 2017.1 EAP 2), but we could easily add it. But first let's consider the problem and improvements C# 7.0 brings us.

Pattern matching at if statement with is operator

For example, consider this code:

if (obj is FooType)
{
    var fooObj = (FooType)obj;
    // continue to work with fooObj
}

Than's not really good as it requires double type checking (and writing the type name twice - which is error prone). For years we've used this approach instead:

var fooObj = obj as FooType;
if (fooObj != null)
{
    // continue to work with fooObj       
}

But it has its own drawbacks - fooObj variable could be accessed outside of the scope of the if block without any compiler errors.

C# 7.0 brings support for pattern matching feature allowing to simplify this dramatically:

if (obj is FooType fooObj)
{
    // continue to work with fooObj       
}

That's perfect! Much less code and fooObj variable is not accessible outside of scope - compiler error: Use of unassigned local variable fooObj.

ReSharper improvements

So how we can make ReSharper learn about automatic suggestion and even automatic code rewriting for cases when you had code with as? Use "Search with pattern" feature! Let's create a simple pattern for search and replace. Open ReSharper menu->Find->Search with pattern and setup search expression this way: (the screenshot is displayed at the end of this page)

$type$ $varName$ = $fromVarName$ as $type$;
if ($varName$ != null)
{
   $statements$
}

Do not forget to set proper types for the defined variables:

  • $type$ means type
  • $varName$ means identifier
  • $fromVarName$ means identifier
  • $statements$ means "any number of statements"

Now you can try to find code matching this pattern. It will output results to the ReSharper Find results window (which sometimes doesn't open automatically, you can open it from ReSharper menu->Windows->Find results).

Now let's write replace pattern for this search pattern:

if ($fromVarName$ is $type$ $varName$)
{
   $statements$
}

(don't forget to check the "Format after replacement" checkbox)

Then we can save it - to promote it to the Custom patterns used by ReSharper for automatic code analysis, suggestions and replacement! After saving you can find it in ReSharper menu->Options->(Code inspection)->Custom patterns. You could set any severity you want - even Error. Then you could use auto-fix (Alt+Enter) to apply the automatic replacement.

Regards!

Vladimir Kozlov aka ai_enabled AtomicTorch Studio Pte. Ltd.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment