ReSharper Annotations. Can it be null?
Published on
Hi,
ReSharper is doing a great job when it comes to semantics of your code and control flow graph analysis. The special edge case I want to talk about is nullness analysis.
Unfortunately, sometimes it’s hard to predict whether the method returns null or it doesn’t.
To solve this problem, R# provides an option to annotate your code.
Let’s look at this snippet:
public Bar Foo()
{
return Random.NextDouble() < 0.1
? null
: new Bar();
}The Foo() returns null with a probability of 10%. However, ReSharper doesn’t warn us when we forget the null-check.
without annotation
A developer can mark the code with [CanBeNull] attribute in order to give a hint to ReSharper.
with annotation
Unfortunately, this trick doesn’t work with asynchronous code.
What if we have a code like this:
[CanBeNull]
public async Task<Bar> FooAsync()
{
await DoAsync();
return Random.NextDouble() < 0.1
? null
: new Bar();
}Despite the fact that we return null here, the actual return type is Task<Bar>. Which is not null, by the way. So the annotation is wrong as well as the warning given to us by R#.
attribute applied to Task, but not to Bar
I was always missing the ability to express that it’s not the Task<T> which can be null, but the Task<T>.Result.
There was even an issue created back in 2013 and finally, in ReSharper 9.2 we have support for brand new [ItemCanBeNull] and [ItemNotNull] attributes.
ItemCanBeNull in action
Both attributes can be applied to IEnumerable<T>, Lazy<T>, and Task<T>
ItemCanBeNull applied to Lazy
Happy annotating!
Links
- How to use JetBrains Annotations to improve ReSharper inspections
- Using Annotations to Refine Code Inspection
- JetBrains.Annotations NuGet package