{"id":17182385,"url":"https://github.com/simoncropp/nullabilityinfo","last_synced_at":"2025-04-13T16:21:14.151Z","repository":{"id":42576053,"uuid":"398933098","full_name":"SimonCropp/NullabilityInfo","owner":"SimonCropp","description":"Exposes top-level nullability information from reflection","archived":false,"fork":false,"pushed_at":"2025-04-09T00:41:19.000Z","size":426,"stargazers_count":15,"open_issues_count":0,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-12T00:28:48.607Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SimonCropp.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"license.txt","code_of_conduct":"code_of_conduct.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"SimonCropp"}},"created_at":"2021-08-23T00:48:41.000Z","updated_at":"2025-04-09T10:19:10.000Z","dependencies_parsed_at":"2024-02-17T06:25:37.350Z","dependency_job_id":"90f39ac8-c187-4821-b916-523fe5f6563c","html_url":"https://github.com/SimonCropp/NullabilityInfo","commit_stats":{"total_commits":439,"total_committers":6,"mean_commits":73.16666666666667,"dds":0.2870159453302962,"last_synced_commit":"2280104aad0da356f2cf87a9c0624e3343b03b69"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SimonCropp%2FNullabilityInfo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SimonCropp%2FNullabilityInfo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SimonCropp%2FNullabilityInfo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SimonCropp%2FNullabilityInfo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SimonCropp","download_url":"https://codeload.github.com/SimonCropp/NullabilityInfo/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248741844,"owners_count":21154385,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-15T00:36:56.642Z","updated_at":"2025-04-13T16:21:14.127Z","avatar_url":"https://github.com/SimonCropp.png","language":"C#","funding_links":["https://github.com/sponsors/SimonCropp"],"categories":[],"sub_categories":[],"readme":"# \u003cimg src=\"/src/icon.png\" height=\"30px\"\u003e NullabilityInfo\n\n[![Build status](https://ci.appveyor.com/api/projects/status/636i70gvxfuwdq38?svg=true)](https://ci.appveyor.com/project/SimonCropp/NullabilityInfo)\n[![Nullability.Source NuGet Status](https://img.shields.io/nuget/v/Nullability.Source.svg?label=Nullability.Source)](https://www.nuget.org/packages/Nullability.Source/)\n[![Nullability NuGet Status](https://img.shields.io/nuget/v/Nullability.svg?label=Nullability)](https://www.nuget.org/packages/Nullability/)\n\nExposes top-level nullability information from reflection.\n\n**See [Milestones](../../milestones?state=closed) for release notes.**\n\nThis feature is [included in net6](https://github.com/dotnet/runtime/issues/29723). This project exposes the APIs to lower runtime. It supports `netstandard2.0` and up.\n\nThis project ships two packages:\n\n\n## Nullability.Source\n\nhttps://nuget.org/packages/Nullability.Source/\n\nA source-only nuget designed to be compatible for libraries that are targeting multiple frameworks including `net6`. In `net5` and below the source files shipped in this nuget are used. In `net6` and up the types from `System.Runtime.dll` are used.\n\n\n## Nullability\n\nhttps://nuget.org/packages/Nullability/\n\nA traditional nuget that ships a single assembly `Nullability.dll`. Since this project syncs with the current master from https://github.com/dotnet/runtime, it contains fixes that may not be included in the currently `System.Runtime.dll`. Use the Nullability package to get those fixes.\n\nTo prevent name conflicts the following has been changed:\n\n * `System.Reflection.NullabilityState` =\u003e `Nullability.NullabilityStateEx`\n * `System.Reflection.NullabilityInfoContext` =\u003e `Nullability.NullabilityInfoContextEx`\n\n\n## Copyright / Licensing\n\nThe csproj and nuget config that builds the package is under MIT.\n\nThe content of the nugets are also MIT but are [Copyright (c) .NET Foundation and Contributors](https://github.com/dotnet/runtime/blob/main/LICENSE.TXT)\n\n\n## Usage\n\n\n### Example target class\n\nGiven the following class\n\n\u003c!-- snippet: Target.cs --\u003e\n\u003ca id='snippet-Target.cs'\u003e\u003c/a\u003e\n```cs\nclass Target\n{\n    public string? StringField;\n    public string?[] ArrayField;\n    public Dictionary\u003cstring, object?\u003e GenericField;\n}\n```\n\u003csup\u003e\u003ca href='/src/Nullability.Source.Tests/Target.cs#L1-L6' title='Snippet source file'\u003esnippet source\u003c/a\u003e | \u003ca href='#snippet-Target.cs' title='Start of snippet'\u003eanchor\u003c/a\u003e\u003c/sup\u003e\n\u003c!-- endSnippet --\u003e\n\n\n### NullabilityInfoContext\n\nFrom the Nullability.Source package\n\n\u003c!-- snippet: SourceUsage --\u003e\n\u003ca id='snippet-SourceUsage'\u003e\u003c/a\u003e\n```cs\n[Fact]\npublic void Test()\n{\n    var type = typeof(Target);\n    var arrayField = type.GetField(\"ArrayField\");\n    var genericField = type.GetField(\"GenericField\");\n\n    var context = new NullabilityInfoContext();\n\n    var arrayInfo = context.Create(arrayField);\n\n    Assert.Equal(NullabilityState.NotNull, arrayInfo.ReadState);\n    Assert.Equal(NullabilityState.Nullable, arrayInfo.ElementType.ReadState);\n\n    var genericInfo = context.Create(genericField);\n\n    Assert.Equal(NullabilityState.NotNull, genericInfo.ReadState);\n    Assert.Equal(NullabilityState.NotNull, genericInfo.GenericTypeArguments[0].ReadState);\n    Assert.Equal(NullabilityState.Nullable, genericInfo.GenericTypeArguments[1].ReadState);\n}\n```\n\u003csup\u003e\u003ca href='/src/Nullability.Source.Tests/Samples.cs#L6-L29' title='Snippet source file'\u003esnippet source\u003c/a\u003e | \u003ca href='#snippet-SourceUsage' title='Start of snippet'\u003eanchor\u003c/a\u003e\u003c/sup\u003e\n\u003c!-- endSnippet --\u003e\n\n\n### NullabilityInfoContextEx\n\nFrom the Nullability package\n\n\u003c!-- snippet: Usage --\u003e\n\u003ca id='snippet-Usage'\u003e\u003c/a\u003e\n```cs\n[Fact]\npublic void Test()\n{\n    var type = typeof(Target);\n    var arrayField = type.GetField(\"ArrayField\");\n    var genericField = type.GetField(\"GenericField\");\n\n    var context = new NullabilityInfoContextEx();\n\n    var arrayInfo = context.Create(arrayField);\n\n    Assert.Equal(NullabilityStateEx.NotNull, arrayInfo.ReadState);\n    Assert.Equal(NullabilityStateEx.Nullable, arrayInfo.ElementType.ReadState);\n\n    var genericInfo = context.Create(genericField);\n\n    Assert.Equal(NullabilityStateEx.NotNull, genericInfo.ReadState);\n    Assert.Equal(NullabilityStateEx.NotNull, genericInfo.GenericTypeArguments[0].ReadState);\n    Assert.Equal(NullabilityStateEx.Nullable, genericInfo.GenericTypeArguments[1].ReadState);\n}\n```\n\u003csup\u003e\u003ca href='/src/Nullability.Tests/Samples.cs#L7-L30' title='Snippet source file'\u003esnippet source\u003c/a\u003e | \u003ca href='#snippet-Usage' title='Start of snippet'\u003eanchor\u003c/a\u003e\u003c/sup\u003e\n\u003c!-- endSnippet --\u003e\n\n\n### NullabilityInfoExtensions\n\n`NullabilityInfoExtensions` provides static and thread safe wrapper around \u003csee cref=\"NullabilityInfoContext\"/\u003e. It adds three extension methods to each of ParameterInfo, PropertyInfo, EventInfo, and FieldInfo.\n\n * `GetNullabilityInfo`: returns the `NullabilityInfo` for the target info.\n * `GetNullability`: returns the `NullabilityState` for the state (`NullabilityInfo.ReadState` or `NullabilityInfo.WriteState` depending on which has more info) of target info.\n * `IsNullable`: given the state (`NullabilityInfo.ReadState` or `NullabilityInfo.WriteState` depending on which has more info) of the info:\n   * Returns true if state is `NullabilityState.Nullable`.\n   * Returns false if state is `NullabilityState.NotNull`.\n   * Throws an exception if state is `NullabilityState.Unknown`.\n\n\n## API\n\n```\nnamespace System.Reflection\n{\n    public sealed class NullabilityInfoContext\n    {\n        public NullabilityInfo Create(ParameterInfo parameterInfo);\n        public NullabilityInfo Create(PropertyInfo propertyInfo);\n        public NullabilityInfo Create(EventInfo eventInfo);\n        public NullabilityInfo Create(FieldInfo parameterInfo);\n    }\n}\n```\n\n\u003c!-- snippet: NullabilityInfo.cs --\u003e\n\u003ca id='snippet-NullabilityInfo.cs'\u003e\u003c/a\u003e\n```cs\n// \u003cauto-generated /\u003e\n#nullable enable\nusing System.Linq;\n// Licensed to the .NET Foundation under one or more agreements.\n// The .NET Foundation licenses this file to you under the MIT license.\n\nusing System.Collections.ObjectModel;\n\nnamespace System.Reflection\n{\n    /// \u003csummary\u003e\n    /// A class that represents nullability info\n    /// \u003c/summary\u003e\n    sealed class NullabilityInfo\n    {\n        internal NullabilityInfo(Type type, NullabilityState readState, NullabilityState writeState,\n            NullabilityInfo? elementType, NullabilityInfo[] typeArguments)\n        {\n            Type = type;\n            ReadState = readState;\n            WriteState = writeState;\n            ElementType = elementType;\n            GenericTypeArguments = typeArguments;\n        }\n\n        /// \u003csummary\u003e\n        /// The \u003csee cref=\"System.Type\" /\u003e of the member or generic parameter\n        /// to which this NullabilityInfo belongs\n        /// \u003c/summary\u003e\n        public Type Type { get; }\n        /// \u003csummary\u003e\n        /// The nullability read state of the member\n        /// \u003c/summary\u003e\n        public NullabilityState ReadState { get; internal set; }\n        /// \u003csummary\u003e\n        /// The nullability write state of the member\n        /// \u003c/summary\u003e\n        public NullabilityState WriteState { get; internal set; }\n        /// \u003csummary\u003e\n        /// If the member type is an array, gives the \u003csee cref=\"NullabilityInfo\" /\u003e of the elements of the array, null otherwise\n        /// \u003c/summary\u003e\n        public NullabilityInfo? ElementType { get; }\n        /// \u003csummary\u003e\n        /// If the member type is a generic type, gives the array of \u003csee cref=\"NullabilityInfo\" /\u003e for each type parameter\n        /// \u003c/summary\u003e\n        public NullabilityInfo[] GenericTypeArguments { get; }\n    }\n\n    /// \u003csummary\u003e\n    /// An enum that represents nullability state\n    /// \u003c/summary\u003e\n    enum NullabilityState\n    {\n        /// \u003csummary\u003e\n        /// Nullability context not enabled (oblivious)\n        /// \u003c/summary\u003e\n        Unknown,\n        /// \u003csummary\u003e\n        /// Non nullable value or reference type\n        /// \u003c/summary\u003e\n        NotNull,\n        /// \u003csummary\u003e\n        /// Nullable value or reference type\n        /// \u003c/summary\u003e\n        Nullable\n    }\n}\n```\n\u003csup\u003e\u003ca href='/src/Nullability.Source/NullabilityInfo.cs#L1-L67' title='Snippet source file'\u003esnippet source\u003c/a\u003e | \u003ca href='#snippet-NullabilityInfo.cs' title='Start of snippet'\u003eanchor\u003c/a\u003e\u003c/sup\u003e\n\u003ca id='snippet-NullabilityInfo.cs-1'\u003e\u003c/a\u003e\n```cs\n// \u003cauto-generated /\u003e\n#nullable enable\nusing System.Linq;\n// Licensed to the .NET Foundation under one or more agreements.\n// The .NET Foundation licenses this file to you under the MIT license.\n\nusing System.Collections.ObjectModel;\n\nusing NullabilityInfoContext= Nullability.NullabilityInfoContextEx;\nusing NullabilityInfo = Nullability.NullabilityInfoEx;\nusing NullabilityState = Nullability.NullabilityStateEx;\nnamespace Nullability\n{\n    /// \u003csummary\u003e\n    /// A class that represents nullability info\n    /// \u003c/summary\u003e\n    public sealed class NullabilityInfoEx\n    {\n        internal NullabilityInfoEx(Type type, NullabilityState readState, NullabilityState writeState,\n            NullabilityInfo? elementType, NullabilityInfo[] typeArguments)\n        {\n            Type = type;\n            ReadState = readState;\n            WriteState = writeState;\n            ElementType = elementType;\n            GenericTypeArguments = typeArguments;\n        }\n\n        /// \u003csummary\u003e\n        /// The \u003csee cref=\"System.Type\" /\u003e of the member or generic parameter\n        /// to which this NullabilityInfo belongs\n        /// \u003c/summary\u003e\n        public Type Type { get; }\n        /// \u003csummary\u003e\n        /// The nullability read state of the member\n        /// \u003c/summary\u003e\n        public NullabilityState ReadState { get; internal set; }\n        /// \u003csummary\u003e\n        /// The nullability write state of the member\n        /// \u003c/summary\u003e\n        public NullabilityState WriteState { get; internal set; }\n        /// \u003csummary\u003e\n        /// If the member type is an array, gives the \u003csee cref=\"NullabilityInfo\" /\u003e of the elements of the array, null otherwise\n        /// \u003c/summary\u003e\n        public NullabilityInfo? ElementType { get; }\n        /// \u003csummary\u003e\n        /// If the member type is a generic type, gives the array of \u003csee cref=\"NullabilityInfo\" /\u003e for each type parameter\n        /// \u003c/summary\u003e\n        public NullabilityInfo[] GenericTypeArguments { get; }\n    }\n\n    /// \u003csummary\u003e\n    /// An enum that represents nullability state\n    /// \u003c/summary\u003e\n    public enum NullabilityStateEx\n    {\n        /// \u003csummary\u003e\n        /// Nullability context not enabled (oblivious)\n        /// \u003c/summary\u003e\n        Unknown,\n        /// \u003csummary\u003e\n        /// Non nullable value or reference type\n        /// \u003c/summary\u003e\n        NotNull,\n        /// \u003csummary\u003e\n        /// Nullable value or reference type\n        /// \u003c/summary\u003e\n        Nullable\n    }\n}\n```\n\u003csup\u003e\u003ca href='/src/Nullability/NullabilityInfo.cs#L1-L70' title='Snippet source file'\u003esnippet source\u003c/a\u003e | \u003ca href='#snippet-NullabilityInfo.cs-1' title='Start of snippet'\u003eanchor\u003c/a\u003e\u003c/sup\u003e\n\u003c!-- endSnippet --\u003e\n\n\n## How this is built\n\nOn 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.\n\n\n## Icon\n\n[Reflection](https://thenounproject.com/term/reflection/4087162/) designed by [Yogi Aprelliyanto](https://thenounproject.com/yogiaprelliyanto/) from [The Noun Project](https://thenounproject.com).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimoncropp%2Fnullabilityinfo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsimoncropp%2Fnullabilityinfo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimoncropp%2Fnullabilityinfo/lists"}