ReSharper’s code generation actions can create a lot of code for us. Why manually write a constructor that initializes type members? Why manually implement interface methods and properties? ReSharper can do those things for us!
Some say developers who use tools to generate code are lazy. Personally, I like to call that efficient. Instead of writing code that is, in essence, programming language ceremony, we can let ReSharper generate it for us and focus on implementing business value and solving our customer’s problem instead. In this post, we’ll go over some of the newly introduced and updated code generation actions in ReSharper 2016.3.
Generate relational members/comparer (implement IComparable<T>/IComparer<T>)
When we want to be able to compare or sort a class we’re implementing, we have to implement the IComparable interface on it. It features one method,
CompareTo(other), which returns 0 when objects are equal, < 0 when the current object comes before the other, and > 0 when the current object comes after the other.
Here’s a ShoeSize class we want to be able to compare. After pressing Alt+Insert we can generate Relational members. As with any ReSharper generate action, we can then select the fields we want to use, optionally change their order and then let ReSharper generate the code for us – in this case the comparer.
The IComparable interface is great to have for sorting collections and all that, but personally I prefer comparing objects in my code using operators. In other words, I prefer writing
shoeSizeA >= shoeSizeB instead of
shoeSizeA.CompareTo(shoeSizeB) >= 0. Again using Generate relational members we can enable overload relational operators and have ReSharper generate operator overloads for our class.
A cool thing is ReSharper also detects field types. For example if we have a class which contains string fields, ReSharper will let us pick a string comparison option, generate nullability checks and all that.
Generate dispose pattern (implement IDisposable)
When writing code that makes use of external resources, like a file stream, system handle or a database connection, it’s best to always release these resources when we no longer need them. The .NET runtime helps us with this by finalizing such objects, but that’s not ideal as it takes two rounds of garbage collection to remove the objects from memory – essentially keeping the object around in memory for too long.
The dispose pattern helps us release these external resources so that the garbage collector can do its job faster. And ReSharper helps us do our job faster – we can use the quick-fix by pressing Alt+Enter and let ReSharper generate and implement
IDisposable for us.
The dispose pattern code generation lets us select several options where we can help code generation, for example by specifying fields can be null. We also can specify whether we plan to inherit from this class, or if the class owns unmanaged resources. These options are used to implement variations of dispose logic:
- When the class only owns managed resources, a simple
Disposemethod will be generated which in turn calls the
Disposemethod on those resources.
- When the class owns only unmanaged resources, ReSharper will generate a
Disposemethod, a destructor, and a method called
ReleaseUnmanagedResources. We can add our own clean-up logic in this method.
- When the class owns both managed and unmanaged resources, either directly or via inheritance, a
Dispose(bool)method will be generated which can be overridden by inheritors.
Have a class and added some fields and properties to it? Using the Alt+Insert keyboard shortcut, we can generate a constructor for our class. We can select fields, properties and optionally base constructors to call and then let ReSharper generate initialization code. The generated code will assign constructor parameter values to fields and properties. New in ReSharper 2016.3 is that we can (optionally) generate null checks, throwing ArgumentNullException when a parameter is null.
Generate missing members/overrides that are async
In any codebase, we can start off by writing an interface or a base class and then let ReSharper generate a class that implements or inherits these. With ReSharper 2016.3 we’ve added the option to make generated methods async when returning a Task. This speeds up coding since we no longer have to add the async keyword manually and can just start implementing the method bodies.
Several other improvements have been made, such as additional quick-fixes for C# and VB.NET that can invoke these code generation actions.