roslyn: [MaybeNull]: Cannot implement a generic method with a "default" return value with nullable references
I’m trying to implement methods that return an optional of a given type T but get a compiler error. Changing return type to T?
only changes the error.
I understand why compiler provides that error, it makes sense, but I have no idea how I can get around it in the world of nullable references. Should I change the design of such methods?
Version Used: Roslyn_Nullable_References_Preview_09112018
Steps to Reproduce:
public static T FirstOrDefault<T>(this IList<T> list)
{
if (list.Count == 0)
{
return default; // CS8625
}
return list[0];
}
Expected Behavior: The code compiles fine without nullable references. I’d expect it to work the same.
Actual Behavior: Compiler error CS8625: Cannot convert null literal to non-nullable reference or unconstrained type parameter.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 8
- Comments: 18 (11 by maintainers)
Commits related to this issue
- Enable nullable reference types for collection extensions — committed to dotnet/roslyn by sharwell 5 years ago
Wow, one can apply attributes to generic types. I didn’t know it)
Only why does
MaybeNullAttribute
not haveAttributeTargets.GenericParameter
? It could work. But it doesn’t (( Hope in C# 9 you will come up with something.@Denis535 There is not way to return
default
from an async method without warning or suppression at the moment. We are planning to allow aT??
syntax that could be used in this example inTask<T??>
(meaning maybe-null even if the type is non-nullable). Tracked by https://github.com/dotnet/roslyn/issues/29146For the more general question, unconstrained generic types could be nullable or not-nullable. If you consume one, you need to be careful as it may be nullable. If you return one, you need to be careful as it may be not-nullable.
As I wrote in dotnet/csharplang#2194, it seems extremely problematic to change the meaning of
T?
to mean anything other thanNullable<T>
for value types, in any context.Methods like
FirstOrDefault<T>
could be simply be annotated with the[MaybeNull]
proposed here for the same effect.Thanks. This is a known issue.
T?
is currently only valid whenT
is constrained to be a reference type. For unconstrained type parameters, the current plan from LDM is to use an attribute,[MaybeNull]
, to indicate that the value may be null when the type is a reference type. But there are still language design issues with this:T local = list.FirstOrDefault();
would still produce a warning and attributes are not allowed on local declarations…Tagging @cston since he was looking into this recently.
@ssg generic type constraints aren’t part of the method signature, so this can’t work (see https://github.com/dotnet/csharplang/issues/2013).
Our current plan is for nullability attributes like
[return: MaybeNull]
not to affect method bodies. Soreturn default;
would still warn for now. We will look at refining this post C# 8 RTM. This is tracked by https://github.com/dotnet/roslyn/issues/36039 (Should nullability attributes affect method bodies and OHI?)@YohDeadfall The LDM writeup is here. It’s part of a wider suite of attributes.
For whatever it’s worth, I was able to implement this without any compiler errors on .NET Core 3.0 preview 5 and it seems to be working fine (except for non-nullable references, of course):
When you use it, it uses the correct overload depending on the type of the list item.