Search code examples
c#resharperautomated-refactoringridertrygetvalue

Resharper Refactor pattern for TryGetValue in Dictionary


The most cumbersome piece of syntax I need to continually write is lazily initializing a container in a dictionary like:

ContainerRecord value;
if(!_dictionary.TryGetValue(key,out value))
{
   value = new ContainerRecord();
   _dictionary[key] = value;
}
//Container is always initialized here

Which I feel would be a trivial refactor pattern from: (At least for the explicit variable declaration and if statement part)

var value = _dictionary[key];

I know there is some new syntactic sugar in newer versions of C# that eliminate the need for pre-declaring out variables. Unfortunately I don't have access to these features in my environment and won't for the foreseeable future.

There does appear to be a "check for contains key" refactor, which is achieves almost the same result with the downside of doing the lookup twice.

Is this possible through some extension? I figured it is a common enough case that it would have already been solved somewhere.


Solution

  • You can create a Custom Pattern for this.

    1. Open ReSharper | Options....
    2. Go to the Code Inspection | Custom Patterns node.
    3. Click Add pattern button.
    4. Select Replace on the top right of the dialog.
    5. Add the following four placeholders with the Add Placeholder button:

      Type: Identifier Placeholder
      Name: value
      
      Type: Expression Placeholder
      Name: key
      
      Type: Type Placeholder
      Name: type
      
      Type: Expression Placeholder
      Name: dict
      Expression Type: System.Collections.Generic.IDictionary<,>
      
    6. Enter the following as the Search pattern in the text area on the top:

      $type$ $value$ = $dict$[$key$];
      
    7. Enter the following as the Replace pattern in the text area on the bottom:

      $type$ $value$;
      if(!$dict$.TryGetValue($key$, out $value$))
      {
          $value$ = new $type$();
          $dict$[$key$] = $value$;
      }
      
    8. Optional: Fill out the Description on the top. I used Replace with TryGetValue.

    9. Optional: Fill out the Description on the bottom. I used the same.
    10. Optional: Check the Format after replace checkbox.

    The finished dialog should look like this:

    Search Pattern dialog

    1. Click on the Save button.
    2. Back in the Custom Patterns, you can set the severity level for your new pattern on the right side using the dropdown. I selected Suggestion.
    3. Exit the Options by clicking the Save button.

    If you set up everything correctly, ReSharper should mark the matching patterns with the suggested fix:

    Suggestion on hovering

    Suggestion in quick fix menu