{"id":13593644,"url":"https://github.com/Tyrrrz/PolyShim","last_synced_at":"2025-04-09T05:31:51.983Z","repository":{"id":151008114,"uuid":"623372318","full_name":"Tyrrrz/PolyShim","owner":"Tyrrrz","description":"Polyfills for projects targeting older versions of .NET","archived":false,"fork":false,"pushed_at":"2024-05-22T16:37:19.000Z","size":140,"stargazers_count":23,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-05-22T16:46:57.843Z","etag":null,"topics":["backwards-compatibility","compat","compatibility","dotnet","dotnet-core","dotnet-framework","dotnet-standard","polyfill","shim"],"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/Tyrrrz.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":"License.txt","code_of_conduct":null,"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":"Tyrrrz","patreon":"Tyrrrz","custom":["buymeacoffee.com/Tyrrrz","tyrrrz.me/donate"]}},"created_at":"2023-04-04T08:38:15.000Z","updated_at":"2024-05-28T09:53:13.145Z","dependencies_parsed_at":"2024-04-28T17:23:19.660Z","dependency_job_id":"506026cc-a91d-4629-8cb7-ed7b79e8c1ea","html_url":"https://github.com/Tyrrrz/PolyShim","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tyrrrz%2FPolyShim","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tyrrrz%2FPolyShim/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tyrrrz%2FPolyShim/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tyrrrz%2FPolyShim/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Tyrrrz","download_url":"https://codeload.github.com/Tyrrrz/PolyShim/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247986805,"owners_count":21028887,"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":["backwards-compatibility","compat","compatibility","dotnet","dotnet-core","dotnet-framework","dotnet-standard","polyfill","shim"],"created_at":"2024-08-01T16:01:22.605Z","updated_at":"2025-04-09T05:31:51.975Z","avatar_url":"https://github.com/Tyrrrz.png","language":"C#","funding_links":["https://github.com/sponsors/Tyrrrz","https://patreon.com/Tyrrrz","buymeacoffee.com/Tyrrrz","tyrrrz.me/donate"],"categories":["C#","C\\#"],"sub_categories":[],"readme":"# PolyShim\n\n[![Status](https://img.shields.io/badge/status-active-47c219.svg)](https://github.com/Tyrrrz/.github/blob/master/docs/project-status.md)\n[![Made in Ukraine](https://img.shields.io/badge/made_in-ukraine-ffd700.svg?labelColor=0057b7)](https://tyrrrz.me/ukraine)\n[![Build](https://img.shields.io/github/actions/workflow/status/Tyrrrz/PolyShim/main.yml?branch=master)](https://github.com/Tyrrrz/PolyShim/actions)\n[![Coverage](https://img.shields.io/codecov/c/github/Tyrrrz/PolyShim/master)](https://codecov.io/gh/Tyrrrz/PolyShim)\n[![Version](https://img.shields.io/nuget/v/PolyShim.svg)](https://nuget.org/packages/PolyShim)\n[![Downloads](https://img.shields.io/nuget/dt/PolyShim.svg)](https://nuget.org/packages/PolyShim)\n[![Discord](https://img.shields.io/discord/869237470565392384?label=discord)](https://discord.gg/2SUWKFnHSm)\n[![Fuck Russia](https://img.shields.io/badge/fuck-russia-e4181c.svg?labelColor=000000)](https://twitter.com/tyrrrz/status/1495972128977571848)\n\n\u003ctable\u003e\n    \u003ctr\u003e\n        \u003ctd width=\"99999\" align=\"center\"\u003eDevelopment of this project is entirely funded by the community. \u003cb\u003e\u003ca href=\"https://tyrrrz.me/donate\"\u003eConsider donating to support!\u003c/a\u003e\u003c/b\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n\u003c/table\u003e\n\n**PolyShim** is a collection of polyfills that enable many modern BCL and compiler features for projects targeting older versions of .NET.\nIt's distributed as a source-only package that can be referenced without imposing any run-time dependencies.\n\n## Terms of use\u003csup\u003e[[?]](https://github.com/Tyrrrz/.github/blob/master/docs/why-so-political.md)\u003c/sup\u003e\n\nBy 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:\n\n- You **condemn Russia and its military aggression against Ukraine**\n- You **recognize that Russia is an occupant that unlawfully invaded a sovereign state**\n- You **support Ukraine's territorial integrity, including its claims over temporarily occupied territories of Crimea and Donbas**\n- You **reject false narratives perpetuated by Russian state propaganda**\n\nTo learn more about the war and how you can help, [click here](https://tyrrrz.me/ukraine). Glory to Ukraine! 🇺🇦\n\n## Install\n\n- 📦 [NuGet](https://nuget.org/packages/PolyShim): `dotnet add package PolyShim`\n\n\u003e **Important**:\n\u003e To use this package, you must have the latest version of the .NET SDK installed.\n\u003e This is only required for the build process, and does not affect which version of the runtime you can target.\n\n## Features\n\n- Enables compiler support for:\n  - Nullable reference types\n  - Init-only properties and records\n  - Required properties\n  - Named tuples\n  - Module initializers\n  - Overload priority\n  - \u0026 more...\n- Provides type polyfills for:\n  - `ValueTuple\u003c...\u003e`\n  - `Index` and `Range`\n  - `HashCode`\n  - `SkipLocalsInitAttribute`\n  - `CallerArgumentExpressionAttribute`\n  - `ExcludeFromCodeCoverageAttribute`\n  - \u0026 more...\n- Provides method shims for many built-in types\n- Adjusts polyfills based on available capabilities\n- Targets .NET Standard 1.0+, .NET Core 1.0+, .NET Framework 3.5+\n- Imposes no run-time dependencies\n\n## Usage\n\n**PolyShim** polyfills come in two forms:\n- Type polyfills, which define missing built-in types\n- Method polyfills, which define extension methods that shim missing methods on existing built-in types\n\nOnce the package is installed, the polyfills will be automatically added to your project as internal source files.\nYou can then use them in your code by referencing the corresponding types or methods as if they were defined natively.\n\n\u003e **Note**:\n\u003e Polyfills are only applied to types and methods that are not already provided.\n\u003e When a native implementation of a symbol is available — either in the framework or through a referenced [compatibility package](#compatibility-packages) — it will always be prioritized over the corresponding polyfill.\n\n### Type polyfills\n\n**PolyShim** provides various types that are not available natively on older target frameworks.\nThese types are defined within the corresponding `System.*` namespaces and mimic the behavior of their original implementations as closely as possible.\n\nFor example, with **PolyShim** you can use the `Index` and `Range` structs (added in .NET Core 3.0) on any older version of .NET:\n\n```csharp\nusing System;\n\n// On older framworks, these are provided by PolyShim\nvar index = new Index(1, fromEnd: true);\nvar range = new Range(\n    new Index(3),\n    new Index(1, true)\n);\n```\n\nYou can also use compiler features that rely on these types, such as the advanced indexing and slicing operators:\n\n```csharp\nvar array = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };\n\n// On older framworks, these are provided by PolyShim\nvar last = array[^1];\nvar part = array[3..^1];\n```\n\n### Method polyfills\n\n**PolyShim** provides a number of extension methods that act as shims for instance methods that are not available natively on older target frameworks.\nThese 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.\n\nFor example, with **PolyShim** you can use the `String.Contains(char)` method (added in .NET Core 2.0) on any older version of .NET:\n\n```csharp\nvar str = \"Hello world\";\n\n// On older framworks, this is provided by PolyShim\nvar contains = str.Contains('w');\n```\n\n### Compatibility packages\n\nSome features from newer versions of .NET can also be made available on older frameworks using official compatibility packages published by Microsoft.\n**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. \n\nCurrently, **PolyShim** has integration with the following packages:\n- [`System.Diagnostics.Process`](https://nuget.org/packages/System.Diagnostics.Process) — `Process`, `ProcessStartInfo`, etc.\n- [`System.Management`](https://nuget.org/packages/System.Management) — `ManagementObjectSearcher`, etc.\n- [`System.Memory`](https://nuget.org/packages/System.Memory) — `Memory\u003cT\u003e`, `Span\u003cT\u003e`, etc.\n- [`System.Net.Http`](https://nuget.org/packages/System.Net.Http) — `HttpClient`, `HttpContent`, etc.\n- [`System.Runtime.InteropServices.RuntimeInformation`](https://nuget.org/packages/System.Runtime.InteropServices.RuntimeInformation) — `RuntimeInformation`, `OSPlatform`, etc.\n- [`System.Threading.Tasks`](https://nuget.org/packages/System.Threading.Tasks) — `Task`, `Task\u003cT\u003e`, etc.\n- [`System.Threading.Tasks.Extensions`](https://nuget.org/packages/System.Threading.Tasks.Extensions) — `ValueTask`, `ValueTask\u003cT\u003e`, etc.\n- [`System.ValueTuple`](https://nuget.org/packages/System.ValueTuple) — `ValueTuple\u003c...\u003e`, etc.\n- [`Microsoft.Bcl.Async`](https://nuget.org/packages/Microsoft.Bcl.Async) — `Task`, `Task\u003cT\u003e`, etc (wider support than the `System.*` variant).\n- [`Microsoft.Bcl.AsyncInterfaces`](https://nuget.org/packages/Microsoft.Bcl.AsyncInterfaces) — `IAsyncEnumerable\u003cT\u003e`, `IAsyncDisposable`, etc.\n- [`Microsoft.Bcl.HashCode`](https://nuget.org/packages/Microsoft.Bcl.HashCode) — `HashCode`, etc.\n- [`Microsoft.Bcl.Memory`](https://nuget.org/packages/Microsoft.Bcl.Memory) — `Index`, `Range`, etc.\n- [`Microsoft.Net.Http`](https://nuget.org/packages/Microsoft.Net.Http) — `HttpClient`, `HttpContent`, etc (wider support than the `System.*` variant).\n\nFor example, adding a reference to the `System.Memory` package will enable **PolyShim**'s polyfills that offer `Span\u003cT\u003e` and `Memory\u003cT\u003e`-based method overloads on various built-in types, such as `Stream`:\n\n```xml\n\u003cProject\u003e\n\n  \u003cPropertyGroup\u003e\n    \u003cTargetFramework\u003enetstandard2.0\u003c/TargetFramework\u003e\n  \u003c/PropertyGroup\u003e\n\n  \u003cItemGroup\u003e\n    \u003cPackageReference Include=\"PolyShim\" Version=\"*\" /\u003e\n    \u003cPackageReference Include=\"System.Memory\" Version=\"4.5.5\" /\u003e\n  \u003c/ItemGroup\u003e\n\n\u003c/Project\u003e\n```\n\n```csharp\nusing System.Buffers;\nusing System.IO;\n\nusing var stream = /* ... */;\nusing var buffer = MemoryPool\u003cbyte\u003e.Shared.Rent(512);\n\n// System.Memory is referenced, so this polyfill is enabled\nvar bytesRead = await stream.ReadAsync(buffer.Memory);\n```\n\nConversely, adding a reference to the `System.ValueTuple` package will disable **PolyShim**'s own version of `ValueTuple\u003c...\u003e` and related types.\nYou can leverage this to prioritize the official implementation wherever possible, while still relying on the polyfilled version for older target frameworks:\n\n```xml\n\u003cProject\u003e\n\n  \u003cPropertyGroup\u003e\n    \u003cTargetFramework\u003enetstandard1.6\u003c/TargetFramework\u003e\n  \u003c/PropertyGroup\u003e\n\n  \u003cItemGroup\u003e\n    \u003cPackageReference Include=\"PolyShim\" Version=\"*\" /\u003e\n    \u003cPackageReference Include=\"System.ValueTuple\" Version=\"4.5.0\" /\u003e\n  \u003c/ItemGroup\u003e\n\n\u003c/Project\u003e\n```\n\n```csharp\n// System.ValueTuple is referenced, so this polyfill is disabled\n// (the native implementation is used instead)\nvar (x, y) = (\"hello world\", 42);\n```\n\n### Limitations\n\nDespite best efforts, **PolyShim** is not able to polyfill all the missing APIs due to limitations in the C# language.\nAt least until some form of the [Extension Everything](https://github.com/dotnet/csharplang/discussions/5498) feature is implemented, below are some of the things that currently cannot be polyfilled:\n- Properties\n- Indexers\n- Interface implementations\n- Static members","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FTyrrrz%2FPolyShim","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FTyrrrz%2FPolyShim","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FTyrrrz%2FPolyShim/lists"}