.NET Tools
Essential productivity kit for .NET and game developers
Better null checks, string formatting and path completion with JetBrains Annotations
In the previous blog post of our series around using JetBrains Annotations to improve Rider (and ReSharper’s) code analysis, code completion and navigation, we looked at some background: what are these annotations? And how do we add them to our source code? Now that we have them added to our code, we can look at some examples!
In this series:
- Improving Rider and ReSharper code analysis using JetBrains Annotations
- What are JetBrains Annotations – and how to get them?
- Better null checks, string formatting and path completion with JetBrains Annotations
We started our series with some ASP.NET MVC annotations (of which there are many more). Rider and ReSharper support a large number of annotations – let’s look at a few interesting examples.
Better null safety with CanBeNull
/NotNull
/ItemCanBeNull
/ItemNotNull
Rider and ReSharper perform value analysis to help us in detecting possible null
references, redundant comparisons and null
checks. Consider the following code:
static string GetGuidString() => Guid.NewGuid().ToString(); public static void Main(string[] args) { var guidString = GetGuidString(); if (guidString != null) { // ... } }
Our GetGuidString()
method always returns a value, so the guidString != null
is redundant. By decorating it with the [NotNull]
attribute, Rider and ReSharper will inform us the null check is always true (and hence, redundant):
Similarly we can annotate method parameters with these attributes – either manually or when using the Check parameter for null quick fix (via Alt+Enter). Rider and ReSharper will then warn us if we pass an invalid value:
Writing the full name of the attribute can be cumbersome. Rider and ReSharper will add [CanBeNull]
when we use the ?
type assist, and [NotNull]
when using the !
type assist:
We can use the ItemCanBeNull
/ItemNotNull
annotations with implementations of IEnumerable
, Task
and Lazy
classes to indicate that the value of a collection item, of the Task.Result
property or of the Lazy.Value
property can or can never be null.
Better string formatting with with StringFormatMethod
Using the StringFormatMethod
annotation, we can indicate that a method works similar to the string.Format
method. When we use the annotation, Rider and ReSharper will know our method takes a composite format string, followed by arguments that will replace the placeholders in the format string. All of a sudden, we get syntax highlighting, code analysis and code completion for the placeholders, including formatting!
File-system completion with PathReference
When annotating a class member (such as a property) or a method parameter with PathReference
, we will get code completion for files and folders within our project. Paths can be relative or absolute, starting from the web root (~
). The PathReference
annotation also provides navigation to the specified path!
What other annotations are there?
There are many more annotations we can use to make Rider and ReSharper better at helping us.
NotifyPropertyChangedInvocator
is great when writing a class that implements theINotifyPropertyChanged
interface and opens access to a number of additional context actions on properties (such as automatically creating a backing field and adding change notification.- The
RegexPattern
annotation makes a field, property or parameter a regular expression, providing syntax highlighting, code completion and validation of our regular expression. ContractAnnotation
describes the relation between method input and output, for example by telling Rider and ReSharper that when a null value is passed, a null value will be returned.Pure
indicates that a method does not make any observable state changes, ensuring callers that there will be no side effects from calling that method. The[Pure]
annotation not only allows to find places where return values are ignored, it also makes some analyses more precise.PublicAPI
indicates a method is exposed as a public API, and therefore marked as “used” by code analysis. This will prevent Rider and ReSharper from graying it out because it looks unused.- And many, many more! Do check our web help for a full overview of all available annotations and examples of how to use them.
Download the latest Rider or give ReSharper a try! We’d love to hear your feedback!