mu88 Developer Blog Buy me a coffee

Structural Search and Replace

Last week, I implemented the following little extension method to make the conversion between DateTime and DateOnly more concise:

using System;

namespace My.Extensions;

public static class DateTimeExtensions
{
    // ReSharper disable once replace.dateonly.fromdatetime.by.todateonly
    public static DateOnly ToDateOnly(this DateTime dateTime) => DateOnly.FromDateTime(dateTime);
}

Especially in automated tests, I love using the Fluent Assertions for dates and times because it makes the following more readable:

// old
var dateOnly = DateOnly.FromDateTime(12.April(1953));

// new
var dateOnly = 12.April(1953).ToDateOnly();

Aside this little extension method and the corresponding changes, I added a ReSharper Search Pattern to the pull request for automatically suggesting to use the extension method:

Since my fellow reviewing colleague was not aware of this feature, I decided to dedicate it a blog post.

Structural Search and Replace

This is another member out of the collection tiny but powerful ReSharper features many people are not aware of. As usual, the official JetBrains docs are pretty extensive, but put in my own very few words: this feature allows you to search your code not only textual but syntactical for certain patterns (e. g. with exactly one argument of a given type).

Not only can you search for those patterns, you can define replacement patterns and a custom severity - in my case it’s highlighted as a Suggestion.

And last but not least, these refactorings are saved within the typical ReSharper *.DotSettings file, making it possible to keep your personal collection of refactorings or share them with you fellow colleagues via YourSolution.sln.DotSettings.
It is a very lightweight approach, especially for such relatively small refactorings, and is therefore superior to a Roslyn Analyser because I don’t like creating another assembly just for such a one-liner.

How to configure

At the moment of writing, there is no way to configure this in Rider (please upvote this JetBrains issue) - so it’s one of those rare times when I open Visual Studio, load the Solution that I want the refactoring to apply to and navigate to ReSharper | Options | Code Inspection | Custom Patterns.

For example, my previously shown refactoring looks like this:

Note that by specifying a Suppression key, you can even instruct ReSharper to ignore a particular finding.

As you might have noticed, I’ve added the following comment to the extension method:
// ReSharper disable once replace.dateonly.fromdatetime.by.todateonly
This way ReSharper doesn’t suggest to use my extension method here as well, because otherwise it would end with the following recursive path:

After saving the pattern to the corresponding layer, we’re ready to go 💪🏻 no need for Visual Studio anymore, so it can be closed and after opening the Solution again in Rider, the new refactoring hint becomes available. Finally, don’t forget to create a pull request to share it with your colleagues.

Closing

I hope I could show you another little helper for your tool belt that you can use the next time when a dedicated Roslyn analyzer feels just too much.

Thank you for reading and take care!

Buy me a coffee