Kjell Rilbe
Kjell Rilbe

Reputation: 1509

Instruct null checking that async result cannot be null?

Let's say I have a method like this:

Task<T> GetThingAsync(long id);

Let's assume that this method will always return non-null T (or throw).

Then, let's say I call it:

public async void Method(IRepository<Entity> repo)
{
    var x = await repo.GetThingAsync(0);
    if (x != null)
        x.Id += x.Id; // Dummy code of course.
}

Then xends up with type Entity? rather than Entity.

Also at the subsequent two lines, IntelliSense(?) says that x is not null there, but it doesn't produce a hint that the if isn't necessary.

I realize that the choice of type Entity? makes sense considering the subsequent code may want to set the variable to null at some point.

But is there some way I can get a hint that it's unnecessary to check if the variable is null? Or would that be a new feature wish?

Upvotes: 1

Views: 84

Answers (2)

Lajos Arpad
Lajos Arpad

Reputation: 76953

You can have a method in a class like this:

T ExtractIfPossible(T? obj) {
    return obj.HasValue ? obj.Value : null;
}

and then you can do:

var x = myHandler.ExtractValueIfPossible(await repo.GetByIdAsync(0));

Of course, you will need to instantiate myHandler and make it generic, possibly using factory methods to do so.

Upvotes: 0

Emad Kerhily
Emad Kerhily

Reputation: 280

While IntelliSense may not always give hints about unnecessary null checks, you can aid the compiler by using attributes like [NotNull] to assert that a method will never return null. This can make your code cleaner and remove unnecessary checks. First, make sure to include the necessary namespace for the attributes:

using System.Diagnostics.CodeAnalysis;

Now, update the method to indicate non-nullability:

public class Repository<Entity> : IRepository<Entity> where Entity : class, new()
{
    [return: NotNull]
    public Task<Entity> GetByIdAsync(long id)
    {
        // Dummy return for illustration
        return Task.FromResult(new Entity());
    }
}

In your calling method, the nullability hint will be respected:

public async void Method(IRepository<Entity> repo)
{
    var x = await repo.GetByIdAsync(0);
    // No need for null check because the GetByIdAsync is marked as [NotNull]
    x.Id += x.Id; // Dummy code of course
}

Upvotes: 3

Related Questions