Skip to content

NullabilityInfoContext reporting incorrect nullability for ParameterInfo of generic types #92487

Closed

Description

@eiriktsarpalis

Description

When it comes to generic types, it is not possible for the NullabilityInfoContext class to determine the nullability of members whose type is a generic parameter -- in such cases NullabilityInfoContext will fall back to reporting the members as being Nullable. This works fine for the cases of PropertyInfo and FieldInfo, however I found a case where the nullability of a ParameterInfo is reported erroneously as NotNull.

Reproduction Steps

Type type = typeof(MyPoco<string>);
var ctx = new NullabilityInfoContext();

// Property nullability -- works as expected
PropertyInfo prop = type.GetProperties()[0];
NullabilityInfo propNullability = ctx.Create(prop);
Console.WriteLine(propNullability.ReadState); // Nullable

// Parameter nullability -- ReadState & WriteState reported as NotNull
var param = type .GetConstructors()[0].GetParameters()[0];
var info = ctx.Create(param);
Console.WriteLine(info.ReadState); // NotNull
Console.WriteLine(info.WriteState); // NotNull

public class MyPoco<T>
{
    public MyPoco(T value) => Value = value;
    public T Value { get; }
}

Expected behavior

Parameter nullability should be reported as Nullable, similar to the property.

Actual behavior

Reported as NotNull.

Regression?

No response

Known Workarounds

No response

Configuration

No response

Other information

Adding a notnull constraint makes nullability information being reported as expected:

var ctx = new NullabilityInfoContext();

Type type = typeof(MyPoco<string>);
PropertyInfo prop = type.GetProperties()[0];
NullabilityInfo propNullability = ctx.Create(prop);
Console.WriteLine(propNullability.ReadState); // NotNull

var param = typeof(MyPoco<string>).GetConstructors()[0].GetParameters()[0];
var info = ctx.Create(param);
Console.WriteLine(info.ReadState); // NotNull
Console.WriteLine(info.WriteState); // NotNull

public class MyPoco<T> where T : notnull
{
    public MyPoco(T value) => Value = value;
    public T Value { get; }
}

Activity

  1. ghost added
    untriagedNew issue has not been triaged by the area owner
    on Sep 22, 2023
  2. added this to the Future milestone on Sep 22, 2023
  3. ghost removed
    untriagedNew issue has not been triaged by the area owner
    on Sep 22, 2023
  4. added
    help wanted[up-for-grabs] Good issue for external contributors
    untriagedNew issue has not been triaged by the area owner
    on Sep 22, 2023
  5. ghost removed
    untriagedNew issue has not been triaged by the area owner
    on Sep 22, 2023
  6. eiriktsarpalis commented on Sep 22, 2023

    @eiriktsarpalis
    MemberAuthor

    Related to #1256

  7. karakasa commented on Sep 23, 2023

    @karakasa
    Contributor

    It's likely because NullabilityInfoContext.CheckParameterMetadataType doesn't handle .ctor

    private void CheckParameterMetadataType(ParameterInfo parameter, NullabilityInfo nullability)

    I have implemented a quick fix. Let me check if it works.

  8. ghost added
    in-prThere is an active PR which will close this issue when it is merged
    on Sep 23, 2023
  9. added a commit that references this issue on Sep 23, 2023
    31afd2a
  10. added a commit that references this issue on Sep 26, 2023
    a1f1624
  11. ghost removed
    in-prThere is an active PR which will close this issue when it is merged
    on Sep 26, 2023
  12. added a commit that references this issue on Oct 3, 2023
    2f1a106
  13. ghost locked as resolved and limited conversation to collaborators on Oct 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions