/NullabilityInfo

Code-only package that exposes top-level nullability information from reflection

Primary LanguageC#MIT LicenseMIT

NullabilityInfo

Build status NuGet Status

Code-only package that exposes top-level nullability information from reflection.

This feature is coming in net6. This package exposes the APIs to lower runtime. It supports netstandard2.0 and up.

Designed to be compatible for libraries that are targeting multiple frameworks including net6.

Copyright / Licensing

The csproj and nuget config that builds the package is under MIT.

The cs files inside the nuget are also MIT but are Copyright (c) .NET Foundation and Contributors

NuGet package

https://nuget.org/packages/NullabilityInfo/

Usage

Example target class

Given the following class

class Target
{
    public string? StringField;
    public string?[] ArrayField;
    public Dictionary<string, object?> GenericField;
}

snippet source | anchor

NullabilityInfoContext

[Fact]
public void Test()
{
    var type = typeof(Target);
    var arrayField = type.GetField("ArrayField");
    var genericField = type.GetField("GenericField");

    var context = new NullabilityInfoContext();

    var arrayInfo = context.Create(arrayField);

    Assert.Equal(NullabilityState.NotNull, arrayInfo.ReadState);
    Assert.Equal(NullabilityState.Nullable, arrayInfo.ElementType.ReadState);

    var genericInfo = context.Create(genericField);

    Assert.Equal(NullabilityState.NotNull, genericInfo.ReadState);
    Assert.Equal(NullabilityState.NotNull, genericInfo.GenericTypeArguments[0].ReadState);
    Assert.Equal(NullabilityState.Nullable, genericInfo.GenericTypeArguments[1].ReadState);
}

snippet source | anchor

NullabilityInfoExtensions

NullabilityInfoExtensions provides static and thread safe wrapper around . It adds three extension methods to each of ParameterInfo, PropertyInfo, EventInfo, and FieldInfo.

  • GetNullabilityInfo: returns the NullabilityInfo for the target info.
  • GetNullability: returns the NullabilityState for the state (NullabilityInfo.ReadState or NullabilityInfo.WriteState depending on which has more info) of target info.
  • IsNullable: given the state (NullabilityInfo.ReadState or NullabilityInfo.WriteState depending on which has more info) of the info:
    • Returns true if state is NullabilityState.Nullable.
    • Returns false if state is NullabilityState.NotNull.
    • Throws an exception if state is NullabilityState.Unknown.

API

namespace System.Reflection
{
    public sealed class NullabilityInfoContext
    {
        public NullabilityInfo Create(ParameterInfo parameterInfo);
        public NullabilityInfo Create(PropertyInfo propertyInfo);
        public NullabilityInfo Create(EventInfo eventInfo);
        public NullabilityInfo Create(FieldInfo parameterInfo);
    }
}

#nullable enable
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.ObjectModel;

namespace System.Reflection
{
    /// <summary>
    /// A class that represents nullability info
    /// </summary>
    sealed class NullabilityInfo
    {
        internal NullabilityInfo(Type type, NullabilityState readState, NullabilityState writeState,
            NullabilityInfo? elementType, NullabilityInfo[] typeArguments)
        {
            Type = type;
            ReadState = readState;
            WriteState = writeState;
            ElementType = elementType;
            GenericTypeArguments = typeArguments;
        }

        /// <summary>
        /// The <see cref="System.Type" /> of the member or generic parameter
        /// to which this NullabilityInfo belongs
        /// </summary>
        public Type Type { get; }
        /// <summary>
        /// The nullability read state of the member
        /// </summary>
        public NullabilityState ReadState { get; internal set; }
        /// <summary>
        /// The nullability write state of the member
        /// </summary>
        public NullabilityState WriteState { get; internal set; }
        /// <summary>
        /// If the member type is an array, gives the <see cref="NullabilityInfo" /> of the elements of the array, null otherwise
        /// </summary>
        public NullabilityInfo? ElementType { get; }
        /// <summary>
        /// If the member type is a generic type, gives the array of <see cref="NullabilityInfo" /> for each type parameter
        /// </summary>
        public NullabilityInfo[] GenericTypeArguments { get; }
    }

    /// <summary>
    /// An enum that represents nullability state
    /// </summary>
    enum NullabilityState
    {
        /// <summary>
        /// Nullability context not enabled (oblivious)
        /// </summary>
        Unknown,
        /// <summary>
        /// Non nullable value or reference type
        /// </summary>
        NotNull,
        /// <summary>
        /// Nullable value or reference type
        /// </summary>
        Nullable
    }
}

snippet source | anchor

How this is built

On every build the NullabilityInfo.csproj downloads NullabilityInfo.cs and NullabilityInfoContext.cs. This ensures that the bundled files are always up to date on each release.

Icon

Reflection designed by Yogi Aprelliyanto from The Noun Project.