Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CanBeNull and ReSharper - using it with async Tasks?

Tags:

c#

resharper

I recently figured out that you can use the [CanBeNull] annotation in C# to tell ReSharper (and other addons) that a method can return null. This is great, because it makes ReSharper remind me when I don't handle those situations.

However, for async methods that return a Task or a Task<T>, the behavior is unexpected.

For instance, consider this example:

[CanBeNull]
public async Task<string> GetSomeName() {
    var time = DateTime.Now;
    if(time.Second == 30) { 
        return "Jimmy"; 
    } else {
        return null;
    }
}

I know that this scenario is a bit weird, but for simplicity, bear with me. If I (with ReSharper enabled) then try to invoke the method elsewhere, it warns incorrectly. For instance:

var myValue = await GetSomeName();
var subValue = myValue.Trim(); //here, ReSharper should warn me that subValue is null.

Here, ReSharper warns me at the incorrect place. The first line generates a warning (and it claims that the task itself can actually be null, which is wrong). The second line doesn't generate a warning, which is where the warning should have been.

If I were to comply with ReSharper entirely, this code would have to be written:

var myTask = GetSomeName();
if(myTask != null) { 
    //this is silly, and is always true, but ReSharper thinks that the Task can be null due to the CanBeNull attribute.

    var myValue = await myTask;
    var subValue = myValue.Trim(); //this could generate an error, but ReSharper doesn't warn me.

}

Is this a bug with ReSharper that I should submit? Or am I using the annotation incorrectly? I guess we can all agree that the task itself can't ever be null, so I don't know how this makes sense.

like image 460
Mathias Lykkegaard Lorenzen Avatar asked Oct 31 '13 11:10

Mathias Lykkegaard Lorenzen


2 Answers

Ivan Serduk said here:

Starting from ReSharper 9.2 EAP4 attributes "ItemCanBeNull" and "ItemNotNull" can be applied to entities of type "Task<T>" and "Lazy<T>"

It works perfect!

P.S. Please don't forget to update JetBrains Annotations.

like image 164
odinmillion Avatar answered Nov 13 '22 15:11

odinmillion


You've hit a limitation of ReSharper's null value analysis. It is trying to treat the return value (the task) as potential null, rather than the result. However, that's a great feature request - I'd suggest voting for this issue: http://youtrack.jetbrains.com/issue/RSRP-376091

like image 7
citizenmatt Avatar answered Nov 13 '22 16:11

citizenmatt