2
votes

In C#8 we can now enable nullables, which means that reference types by default are considered not null by the compiler unless explicitly declared as nullable. Yet, it seems the compiler still throws a warning when trying to return a default generic with the notnull constraint. Consider the following example:

public TReturn TestMethod<TReturn>() where TReturn : notnull
{
    return default; // default is flagged with a compiler warning for possible null reference return
}

I thought maybe it would help if I also enforced that the return type must have an empty constructor, but it produces the same result:

public TReturn TestMethod<TReturn>() where TReturn : notnull, new()
{
    return default; // default is flagged with a compiler warning for possible null reference return
}

Why is the compiler flagging this line?

1
wait... new() does not mean "empty constructor" - T.S.
default still means null for reference types. - juharr
I’m pretty certain default will always return null for classes. It won’t attempt to construct a new instance, even if there’s a default constructor. - Jeremy Caney
@HotN: With the new() constraint in place, you could instead call return new TReturn(). - Jeremy Caney
@JeremyCaney "parameterless" means "has no parameters". "empty" means "has no body". I suspect that OP meant the former. - D Stanley

1 Answers

2
votes

TReturn : notnull means that TReturn must be a non-nullable type (which can be either a value type or a non-nullable reference type). Unfortunately, the value of default for non-nullable reference types is still null, hence the compiler warning.

If you want the "default" for a non-nullable reference type to be whatever is created with a parameterless constructor, for example, you could do:

public TReturn TestMethod<TReturn>() where TReturn : notnull, new()
{
    return new TReturn(); 
}