ReSharper and Rider continuously analyze the code we’re working on and help us detect errors and problems early on. They provide suggestions and hints as well, and for many of the 2300+ code inspections that are available, quick-fixes exist to automatically resolve detected issues. ReSharper 2017.2, as well as the Rider 2017.2 EAP, introduce several new code inspections and quick-fixes that help us write better code. Let’s have a look.
IEnumerable – Possible multiple enumeration
The Possible multiple enumeration of IEnumerable code inspection has been around for a while. It helps making sure we’re not enumerating a collection twice – something which could lead to excess work of a database or even to mutated state and strange results. ReSharper 2017.2 adds support for
ParallelQuery, next to the already existing inspection for
IEnumerable. Let’s look at what it does.
Consider the following code snippet:
IEnumerable<string> names = GetNamesFromDatabase();
foreach (var name in names)
Console.WriteLine("Name: " + name);
In this piece of code, we’re enumerating the
names sequence twice: once when calling
names.Any(), and a second time when iterating over it.
Now what could happen? A couple of things. First of all, we’re probably running the query executed by
GetNamesFromDatabase() twice. This is wasteful and puts unnecessary load on the database. And while in this example the chance is slim, the database may have new or deleted records between the call to
Any() and iterating over the sequence, which could lead to strange behaviour of our application.
The solution? Making sure we iterate only once, by converting the sequence to an array or a list using
.ToList(). And that’s exactly what the Possible multiple enumeration code inspection and its corresponding quick-fix does:
Note that the quick-fix checks for the type of our
IEnumerable: if it’s already a
List or array, there is no use in converting it again.
Possibly unintended transformation from IQueryable to IEnumerable
When working with objects that implement the
IQueryable interface, we’re most probably working with their underlying LINQ provider. For example when using Entity Framework, we could have a
DbSet which is an
IQueryable. Whenever we run a LINQ query against it, we’re usually making a database call.
IQueryable interface inherits from
IEnumerable, there could be cases where we implicitly convert the
IEnumerable. This could result in memory spikes (converting lots of objects into memory) or slow performance (local processing instead of processing on the database)
Consider the following code:
public static void Example()
using (var databaseContext = new DatabaseContext())
var names = databaseContext.Names.WhereNameStartsWith("M");
public static IEnumerable<string> WhereNameStartsWith(this IEnumerable<string> items, string startsWith)
return items.Where(item => item.StartsWith(startsWith, StringComparison.OrdinalIgnoreCase));
When we call the
.WhereNameStartsWith() extension method, we’re implicitly converting the
IQueryable provided by the database context to an
IEnumerable and running the filter in code (and not on the database).
That’s probably fine and intended, but team members (or our future self) could add additional LINQ queries on top of this, expecting them to run on the database and unwillingly introducing a potential performance issue. We can let the IDE add an explicit
.AsEnumerable() for us:
Initialize auto-property from parameter context action
When using the Introduce auto-property from parameter quick-fix, we could already generate an auto-property with various options, such as making it get-only, adding a private setter, making it mutable, …
The Initialize auto-property from parameter context action now provides similar options, making it very easy to add a property from a constructor parameter: