The problem
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
Substitute.For<IMyTypeToMock>();
method.
If I wanted to use NSubstitute to provide the argument for my GenericMethod
I’d have to do quite a lot of typing:
type Su
or few more characters to position completion on the Substitute
class.
Press Enter
.
Type .
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 NSub
.
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:
NSubstitute.Substitute.For<$type$>()
The $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.
Result
Now your template will be available in the code completion.
All it takes to get to the end result now is to type ns
, Enter
, Enter
.
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.