2

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?

8
  • 1
    wait... new() does not mean "empty constructor" Commented May 20, 2020 at 18:25
  • 4
    default still means null for reference types. Commented May 20, 2020 at 18:27
  • 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. Commented May 20, 2020 at 18:29
  • 1
    @HotN: With the new() constraint in place, you could instead call return new TReturn(). Commented May 20, 2020 at 18:34
  • 3
    @JeremyCaney "parameterless" means "has no parameters". "empty" means "has no body". I suspect that OP meant the former. Commented May 20, 2020 at 18:34

1 Answer 1

2

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(); 
}
Sign up to request clarification or add additional context in comments.

4 Comments

Why not just use return new TReturn() with the ‘new()` constraint? That guarantees a parameterless constructor, and is simpler syntactically.
@JeremyCaney I had thought new() only worked for reference types - I was wrong...
Will this work if TReturn is a Guid? I'm worried that it won't be Guid.Empty.
This won't work if TReturn is string since it doesn't have a parameterless constructor.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.