Anatolii Humennyi
Anatolii Humennyi

Reputation: 1856

Why is there nullability warning for explicitly declared reference return value?

I enabled Nullability context for my test project and tried to fix all nullability warnings. I was able to fix them all except the below one which I don't understand (at return ref book; line). I pasted the warning in the comment at this line that the compiler produces:

class Program
{
    private Book[] books = { new Book("Call of the Wild, The", "Jack London"),
                    new Book("Tale of Two Cities, A", "Charles Dickens") };
    private Book? nobook = null;

    public ref Book? GetBookByTitle(string title)
    {
        for (int ctr = 0; ctr < books.Length; ctr++)
        {
            ref Book book = ref books[ctr];
            if (title == book.Title)
                return ref book; //CS8619: Nullability of reference types in value of type 'Book' doesn't match target type 'Book?'.
        }
        return ref nobook;
    }
}

public class Book
{
    public readonly string Title;
    public readonly string Author;

    public Book(string title, string author)
    {
        Title = title;
        Author = author;
    }
}

I don't understand why the compiler is not satisfied with the non-nullable variable ref Book book that is returned in the method as nullable ref Book?

As I know we can assign non-nullable variables to nullable variables and it's presented below. And as the code below shows the compiler doesn't see any problems if I return non-ref Book book variable in the method with Book? type:

    public Book? GetBookCopyByTitle(string title)
    {
        for (int ctr = 0; ctr < books.Length; ctr++)
        {
            ref Book book = ref books[ctr];
            if (title == book.Title)
                return book; //no warning here. The compiler is satisfied if we don't use ref return value
        }
        return null;
    }

Why the compiler produces in the first code snippet this error:

Nullability of reference types in value of type 'Book' doesn't match target type 'Book?'.

Upvotes: 2

Views: 805

Answers (1)

Sweeper
Sweeper

Reputation: 270733

The error occurs because you are using ref returns here.

Recall the meaning of ref returns. You are returning the reference to a variable, and the caller can change the value of the variable using the reference.

GetBookByTitle is declared to return a nullable reference. According to the declaration, I can get the reference from the method, and then set it to null:

ref var book = ref GetBookByTitle("Tale of Two Cities, A");
book = null; // book is nullable, right? GetBookByTitle says it will return a nullable reference

Because of the specific title I've passed in, book = null; would be reached, setting the non-nullable books[1] to null! If this is allowed, it would break the safety that nullable reference types brings, so it's not allowed.

Upvotes: 4

Related Questions