All Projects → manuelroemer → Nullable

manuelroemer / Nullable

Licence: mit
A source code only package which allows you to use .NET's nullable attributes in older target frameworks like .NET Standard 2.0 or the "old" .NET Framework.

Programming Languages

csharp
926 projects

Projects that are alternatives of or similar to Nullable

IsExternalInit
A source code only package which allows you to use C# 9's init and record features in older target frameworks like .NET Standard 2.0 or the "old" .NET Framework by providing a polyfill for the IsExternalInit class.
Stars: ✭ 75 (-29.25%)
Mutual labels:  polyfill, source
Webcrypto Liner
webcrypto-liner is a polyfill that let's down-level User Agents (like IE/Edge) use libraries that depend on WebCrypto. (Keywords: Javascript, WebCrypto, Shim, Polyfill)
Stars: ✭ 98 (-7.55%)
Mutual labels:  polyfill
Scroll Behavior Polyfill
A polyfill for the 'scroll-behavior' CSS-property
Stars: ✭ 76 (-28.3%)
Mutual labels:  polyfill
Match Media
Universal polyfill for match media API using Expo APIs on mobile
Stars: ✭ 95 (-10.38%)
Mutual labels:  polyfill
Webpack Polyfill Injector
Webpack plugin to automatically inject polyfills into your bundle without affecting modern browsers.
Stars: ✭ 84 (-20.75%)
Mutual labels:  polyfill
Polyfill
PHP polyfills
Stars: ✭ 1,333 (+1157.55%)
Mutual labels:  polyfill
Web Bluetooth Polyfill
Windows 10 Web Bluetooth Polyfill
Stars: ✭ 68 (-35.85%)
Mutual labels:  polyfill
Polyfill Util
This component provides binary-safe string functions, using the mbstring extension when available.
Stars: ✭ 1,364 (+1186.79%)
Mutual labels:  polyfill
Polyfill
Polyfill implements newer Ruby features into older versions.
Stars: ✭ 98 (-7.55%)
Mutual labels:  polyfill
Date Time Format Timezone
Surgically polyfills timezone support in Intl.DateTimeFormat API
Stars: ✭ 94 (-11.32%)
Mutual labels:  polyfill
Polyfill Php54
This component provides functions unavailable in releases prior to PHP 5.4.
Stars: ✭ 93 (-12.26%)
Mutual labels:  polyfill
Openwallet Android
The first truly free, libre, and open source light wallet for multiple cryptocurrencies (Bitcoin, Ethereum, Ripple, etc).
Stars: ✭ 86 (-18.87%)
Mutual labels:  source
Shellfuncs
Python API to execute shell functions as they would be Python functions
Stars: ✭ 96 (-9.43%)
Mutual labels:  source
Montreal
A directory of companies, people, and projects that are Open Source and from Montréal.
Stars: ✭ 77 (-27.36%)
Mutual labels:  source
Es6 Promise Polyfill
ES6 Promise polyfill
Stars: ✭ 99 (-6.6%)
Mutual labels:  polyfill
Css Vars Ponyfill
Client-side support for CSS custom properties (aka "CSS variables") in legacy and modern browsers
Stars: ✭ 1,166 (+1000%)
Mutual labels:  polyfill
Joustmania
Raspberry Pi Jousting at its finest
Stars: ✭ 91 (-14.15%)
Mutual labels:  source
Proposal Array Unique
ECMAScript proposal for Deduplicating method of Array
Stars: ✭ 96 (-9.43%)
Mutual labels:  polyfill
Polyfill Php55
This component provides functions unavailable in releases prior to PHP 5.5.
Stars: ✭ 105 (-0.94%)
Mutual labels:  polyfill
React Suspense Polyfill
Polyfill for the React Suspense API 😮
Stars: ✭ 99 (-6.6%)
Mutual labels:  polyfill

Nullable Nuget

Use .NET Core 3.0's new nullable attributes in older target frameworks.

🏃 Quickstart   |   📚 Guides   |   📦 NuGet


You may also want to check out my IsExternalInit project which provides support for C# 9's init and record keywords for older target frameworks.


With the release of C# 8.0, support for nullable reference types has been added to the language. Futhermore, .NET Core 3.0 added new nullable attributes like the AllowNullAttribute which are sometimes required to exactly declare when and how null is allowed in specific code sections.

Unfortunately, these attributes are not available in older target frameworks like .NET Standard 2.0 which makes annotating existing code harder. Luckily, this problem can be solved by re-declaring the attributes as internal classes - the C# compiler will still use them for generating warnings, even though the target framework doesn't support these attributes by itself.

This repository hosts the code for the "Nullable" NuGet Package which, when referenced, adds support for these attributes.

The code for these attributes is added at compile time and gets built into the referencing project. This means that the resulting project does not have an explicit dependency on the Nullable package, because the attributes are not distributed as a library.

Futhermore, the code only gets added to the project if the nullable attributes are not already supported by the target framework. The images below show an example - in the library which targets .NET Standard 2.0, the attributes have been added during the compilation. That is not the case for the library targeting .NET Standard 2.1, because the attributes are available through the .NET BCL there. This allows you to easily multi-target your projects without having to change a single line of code.

.NET Standard 2.0 .NET Standard 2.1
.NET Standard 2.0 .NET Standard 2.1

Compatibility

Nullabe is currently compatible with the following target frameworks:

  • .NET Standard >= 1.0
  • .NET Framework >= 2.0

Please have a look at the guides for additional information on how to install the package for your target framework.

Quickstart

⚠️ Important:
You must use a C# version >= 8.0 with the Nullable package - otherwise, your project won't compile.

The steps below assume that you are using the new SDK .csproj style. Please find installation guides and notes for other project types (for example packages.config) here.

  1. Reference the package
    Add the package to your project, for example via:

    Install-Package Nullable
    
    --or--
    
    dotnet add package Nullable
    
  2. Ensure that the package has been added as a development dependency
    Open your .csproj file and ensure that the new package reference looks similar to this:

    <PackageReference Include="Nullable" Version="<YOUR_VERSION>">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
    
    <!-- This style also works, but is not automatically used by .NET: -->
    <PackageReference Include="Nullable" Version="<YOUR_VERSION>" PrivateAssets="all" />
    

    This is especially important for libraries that are published to NuGet, because without this, the library will have an explicit dependency on the Nullable package.

  3. Build the project
    Ensure that the project compiles. If a build error occurs, you will most likely have to update the C# language version (see next step).

  4. Enable usage of the attributes
    Still in your .csproj file you need to activate the feature to fully use it. The following activation sample is what seems to be the most common use case. But do not hesitate to look at my guides for other considerations.

    <PropertyGroup>
       <!-- a sample list of target frameworks including legacy ones. This list must depend on your needs. -->
      <TargetFrameworks>net472;netstandard2.0;netstandard2.1;netcoreapp3.0</TargetFrameworks>
      <!-- force lang version at least to C#8 to be able to use the feature with all frameworks.-->
      <LangVersion>8.0</LangVersion> <!-- or --> <LangVersion>latest</LangVersion>
      <!-- enable the feature but without warning for legacy frameworks to avoid false positives. -->
      <Nullable>annotations</Nullable>
      <!-- enable the feature including warnings only on top of the most recent framework you target. -->
      <!-- it will serve as a reference for warnings for all others. -->
      <Nullable Condition="'$(TargetFramework)' == 'netcoreapp3.0'">enable</Nullable>
    </PropertyGroup>
    
  5. Build the project and fix warnings
    If you're not starting a new project you will probably get a lot of warnings now, since your code base is not yet annotated. If you don't expect to fix all right now, one solution could be to disable the feature in all files before reviewing each file one by one. For that run the following powershell script to add a #nullable disable directive at the top of each file.

    Get-ChildItem -Recurse -Filter *.cs | ForEach-Object {
      "#nullable disable`n" + (Get-Content $_ -Raw) | Set-Content $_
    }
    

You should now be ready to play with nullable references and the attributes even when targeting legacy frameworks.

Compiler Constants

The included C# file makes use of some compiler constants that can be used to enable or disable certain features.

NULLABLE_ATTRIBUTES_DISABLE

If the NULLABLE_ATTRIBUTES_DISABLE constant is defined, the attributes are excluded from the build. This can be used to conditionally exclude the attributes from the build if they are not required.

In most cases, this should not be required, because the package automatically excludes the attributes from target frameworks that already support these attributes.

NULLABLE_ATTRIBUTES_INCLUDE_IN_CODE_COVERAGE

Because the attributes are added as source code, they could appear in code coverage reports. By default, this is disabled via the ExcludeFromCodeCoverage and DebuggerNonUserCode attributes.

By defining the NULLABLE_ATTRIBUTES_INCLUDE_IN_CODE_COVERAGE constant, the ExcludeFromCodeCoverage and DebuggerNonUserCode attributes are not applied and the nullable attributes may therefore appear in code coverage reports.

Building

Because the package consists of source files, building works differently than a normal .NET project. In essence, no build has to be made at all. Instead, the *.cs files are renamed to *.cs.pp (because otherwise, Visual Studio's solution explorer would display the files in a project which references the package) and then packaged into a NuGet package via a .nuspec file.

The solution contains a _build project which automatically performs these tasks though. You can then find the resulting NuGet package file in the artifacts folder.

Contributing

I don't expect this package to require many changes, but if something is not working for you or if you think that the source file should change, feel free to create an issue or Pull Request. I will be happy to discuss and potentially integrate your ideas!

License

See the LICENSE file for details.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].