While C# compiler provides a decent level of generic parameter type inference there’s a bunch of scenarios where it does not work, and you have to specify the generic parameters explicitly.
One such case is when you invoke a generic method inline, and the return type is the generic type parameter.
In other words, the following scenario:
In this case the compiler won’t infer the generic parameter of
GenericMethod and you have to specify it explicitly.
As helpful as Resharper often is, it also doesn’t currently provide any help (other than placing the cursor at the appropriate location) and you have to specify the type parameter yourself.
Oh the typing!
I’m quite sensitive to friction in my development work, and I found this limitation quite annoying. Especially that the pattern is used quite often.
Specifically the excellent NSubstitute mocking framework is using it for creation of mocks via
If I wanted to use NSubstitute to provide the argument for my
GenericMethod I’d have to do quite a lot of typing:
Su or few more characters to position completion on the
. and assuming the right overload of
For is selected press
Enter again (or press arrow to pick the right overload before that).
Finally, type enough of the expected type’s name for completion to select it, and press
Enter to finish the statement.
It may not look like much but if you’re writing a lot of tests those things add up. It ends up being just enough repetitive typing to break the flow of thoughts and make you concentrate on the irrelevant mechanics (how to create a mock for
IFoo) rather than what your test is supposed to be doing (verifying behavior of
UsesIFoo method when a non-null
arg is passed).
Resharper to the rescue
While there’s no easy way to solve the general problem, we can use Resharper to help us solve it in this specific case with NSubstitute (or any other API, I’m using NSubstitute as an example here).
For that, we’ll write a Smart Template.
How to: writing a Smart Template
Go to Resharper menu, and pick Templates Explorer…
Make sure you’re on the Live Templates tab, and click New Template.
For Shortcut select whatever you want to appear in your code completion for the template, for example
Select the template should be allowed in C# where expression is allowed.
Check Reformat and Shorten qualified references checkboxes and proceed to specifying the template itself, as follows:
$type$ is a template variable, and the grid on the right hand side allows us to associate a macro with it. That’s where the magic happens.
Pick Change macro… and select Guess type expected at this point.
After you’ve done all of that, make sure you save the template.
Now your template will be available in the code completion.
All it takes to get to the end result now is to type
The main benefit though is not the keystrokes you save, but the fact there’s almost no friction to the process, so you don’t get distracted from thinking about logic of your test.