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
Better null safety with
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)
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
ItemNotNull annotations with implementations of
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 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
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 (
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.
NotifyPropertyChangedInvocatoris great when writing a class that implements the
INotifyPropertyChangedinterface and opens access to a number of additional context actions on properties (such as automatically creating a backing field and adding change notification.
RegexPatternannotation makes a field, property or parameter a regular expression, providing syntax highlighting, code completion and validation of our regular expression.
ContractAnnotationdescribes 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.
Pureindicates 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.
PublicAPIindicates 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.