Home > Mobile >  Why can't I assign default to my notnull generic type?
Why can't I assign default to my notnull generic type?

Time:03-11

Consider this class

public sealed record IdValuePair<TId, TValue>
{
    public IdValuePair(TId id, TValue value)
    {
        EnsureArg.HasValue(value, nameof(value));

        Id = id;
        Value = value;
    }

    public IdValuePair(TValue value)
    {
        EnsureArg.HasValue(value, nameof(value));

        Id = default!;
        Value = value;
    }

    public TId Id { get; }
    public TValue Value { get; }
}

Why is it that if I add the generic constraint

where TId : notnull

I am unable to do this assignment, due to the below error:

Id = default;

CS8601 Possible null reference assignment.

Doesn't the notnull constraint ensure that TId is not null?

CodePudding user response:

Consider IdValuePair<string, int>, the default value for string is null. So assigning null to the Id would clearly be illegal, since you promised that it should not be null.

Adding the constraint where TId : notnull constraint would only prevent declarations like IdValuePair<string?, int>. So we would go from a "Possible null reference assignment" to a "Definite null reference assignment".

There is, as far as I know, no generic constraint that restricts a type to either a nullable reference or nullable struct. And this can cause problems in some generic code.

There are a few possible options:

  1. use a struct-constraint. Value types can never be null, so assigning default should be perfectly safe.
  2. Use a new-constraint, and create a new object rather than using default
  3. Create your own Maybe<T> / Option<T> / Nullable<T> type.
  • Related