cloud-eng .nl

ReSharper Annotations. Can it be null?

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.

screenshot without annotation

A developer can mark the code with [CanBeNull] attribute in order to give a hint to ReSharper.

screenshot 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#. screenshot 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 ItemCanBeNull in action

Both attributes can be applied to IEnumerable<T>, Lazy<T>, and Task<T>

ItemCanBeNull applied to Lazy ItemCanBeNull applied to Lazy

Happy annotating!