PolyShim 1.2.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package PolyShim --version 1.2.0
NuGet\Install-Package PolyShim -Version 1.2.0
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="PolyShim" Version="1.2.0">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add PolyShim --version 1.2.0
#r "nuget: PolyShim, 1.2.0"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install PolyShim as a Cake Addin
#addin nuget:?package=PolyShim&version=1.2.0

// Install PolyShim as a Cake Tool
#tool nuget:?package=PolyShim&version=1.2.0

PolyShim

Made in Ukraine Build Coverage Version Downloads Discord Donate Fuck Russia

🟒 Project status: active<sup>[?]</sup>

PolyShim is a collection of polyfills that enable many modern BCL and compiler features for projects targeting older versions of .NET. It's distributed as a source-only package that can be referenced without imposing any run-time dependencies.

Terms of use<sup>[?]</sup>

By using this project or its source code, for any purpose and in any shape or form, you grant your implicit agreement to all the following statements:

  • You condemn Russia and its military aggression against Ukraine
  • You recognize that Russia is an occupant that unlawfully invaded a sovereign state
  • You support Ukraine's territorial integrity, including its claims over temporarily occupied territories of Crimea and Donbas
  • You reject false narratives perpetuated by Russian state propaganda

To learn more about the war and how you can help, click here. Glory to Ukraine! πŸ‡ΊπŸ‡¦

Install

  • πŸ“¦ NuGet: dotnet add package PolyShim

Warning: To use this package, you must have the latest version of the .NET SDK installed. This is only required for the build process, and does not affect which version of the runtime you can target.

Features

  • Enables compiler support for:
    • Nullable reference types
    • Init-only properties and records
    • Required properties
    • Named tuples
    • Module initializers
    • & more...
  • Provides type polyfills for:
    • ValueTuple<...>
    • Index and Range
    • HashCode
    • SkipLocalsInitAttribute
    • CallerArgumentExpressionAttribute
    • ExcludeFromCodeCoverageAttribute
    • & more...
  • Provides method shims for many built-in types
  • Adjusts polyfills based on available capabilities
  • Targets .NET Standard 1.0+, .NET Core 1.0+, .NET Framework 3.5+
  • Imposes no run-time dependencies

Usage

PolyShim polyfills come in two forms:

  • Type polyfills, which define missing built-in types
  • Method polyfills, which define extension methods that shim missing methods on existing built-in types

Once the package is installed, the polyfills will be automatically added to your project as internal source files. You can then use them in your code by referencing the corresponding types or methods as if they were defined natively.

Type polyfills

PolyShim provides various types that are not available natively on older target frameworks. These types are defined within the corresponding System.* namespaces and mimic the behavior of their original implementations as closely as possible.

For example, with PolyShim you can use the Index and Range structs (added in .NET Core 3.0) on any older version of .NET:

using System;

// On older framworks, these are replaced by polyfills
var index = new Index(1, fromEnd: true);
var range = new Range(
    new Index(3),
    new Index(1, true)
);

You can also use compiler features that rely on these types, such as the advanced indexing and slicing operators:

var array = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

// On older framworks, these are replaced by polyfills
var last = array[^1];
var part = array[3..^1];

Method polyfills

PolyShim provides a number of extension methods that act as shims for instance methods that are not available natively on older target frameworks. These extension methods are typically defined within the global namespace, so they can be called on the corresponding types just like instance methods, without any additional using directives.

For example, with PolyShim you can use the String.Contains(char) method (added in .NET Core 2.0) on any older version of .NET:

var str = "Hello world";

// On older framworks, this is replaced by a polyfill
var contains = str.Contains('w');

Compatibility packages

Some features from newer versions of .NET can also be made available on older frameworks using official compatibility packages published by Microsoft. PolyShim automatically detects if any of these packages are installed and adjusts its polyfill coverage accordingly β€” either by enabling additional polyfills that build upon those features, or by disabling polyfills for APIs that are already provided in the compatibility packages.

Currently, PolyShim has integration with the following packages:

For example, adding a reference to the System.Memory package will enable PolyShim's polyfills that offer Span<T> and Memory<T>-based method overloads on various built-in types, such as Stream:

<Project>

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="PolyShim" Version="*" />
    <PackageReference Include="System.Memory" Version="4.5.5" />
  </ItemGroup>

</Project>
using System.Buffers;
using System.IO;

using var stream = /* ... */;
using var buffer = MemoryPool<byte>.Shared.Rent();

// On older framworks, this is replaced by a polyfill
var bytesRead = await stream.ReadAsync(buffer.Memory);

Conversely, adding a reference to the System.ValueTuple package will disable PolyShim's own polyfills for ValueTuple<...> and related types. You can use this approach to prioritize the official implementation where possible, while still relying on the polyfilled version for older target frameworks:

<Project>

  <PropertyGroup>
    <TargetFramework>netstandard1.6;net35;net50</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="PolyShim" Version="*" />
    <PackageReference
            Include="System.ValueTuple"
            Version="4.5.0"
            Condition="'$(TargetFramework)' == 'netstandard1.6'" />
  </ItemGroup>

</Project>
// On .NET 5.0, this will be provided natively
// On .NET Standard 1.6, this will be provided by the System.ValueTuple package
// On .NET Framework 3.5, this will be provided by PolyShim
var (x, y) = ("hello world", 42);

Limitations

Despite best efforts, PolyShim is not able to polyfill all the missing APIs due to limitations in the C# language. At least until some form of the Extension Everything feature is implemented, below are some of the things that currently cannot be polyfilled:

  • Properties
  • Indexers
  • Interface implementations
  • Static members
There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

  • .NETCoreApp 1.1

  • .NETCoreApp 2.2

    • No dependencies.
  • .NETCoreApp 3.1

    • No dependencies.
  • .NETFramework 3.5

    • No dependencies.
  • .NETFramework 4.0

    • No dependencies.
  • .NETFramework 4.5

    • No dependencies.
  • .NETFramework 4.6.1

    • No dependencies.
  • .NETFramework 4.6.2

    • No dependencies.
  • .NETFramework 4.8

    • No dependencies.
  • .NETStandard 1.0

  • .NETStandard 1.1

  • .NETStandard 1.6

  • .NETStandard 2.0

    • No dependencies.
  • .NETStandard 2.1

    • No dependencies.
  • net5.0

    • No dependencies.
  • net7.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories (7)

Showing the top 5 popular GitHub repositories that depend on PolyShim:

Repository Stars
Tyrrrz/CliWrap
Library for running command-line processes
Tyrrrz/YoutubeExplode
Abstraction layer over YouTube's internal API
Tyrrrz/CliFx
Class-first framework for building command-line interfaces
Tyrrrz/Onova
Unintrusive auto-update framework
Tyrrrz/GitHubActionsTestLogger
.NET test logger that reports to GitHub Actions
Version Downloads Last updated
1.10.0 1,808 1/11/2024
1.9.0 984 12/31/2023
1.8.0 2,791 9/19/2023
1.7.0 1,690 8/7/2023
1.6.0 226 8/5/2023
1.5.0 1,761 6/5/2023
1.4.0 520 5/25/2023
1.3.0 220 5/18/2023
1.2.0 2,162 4/14/2023
1.1.0 447 4/5/2023
1.0.0 239 4/4/2023