|
| 1 | + |
| 2 | + |
| 3 | +# What is it? 🚀 |
| 4 | + |
| 5 | +**PolySharp** provides generated, source-only polyfills for C# language features, to easily use all runtime-agnostic features downlevel. The package is distributed as a source generator, so that it will automatically detect which polyfills are needed depending on the target framework and project in use: just add a reference to **PolySharp**, set your C# language version to latest, and have fun! |
| 6 | + |
| 7 | +# TLDR? What is this for? ✨ |
| 8 | + |
| 9 | +Put simply: are you working on .NET Framework, or UWP, or some other older .NET runtime and still would like to use all the cool new features that C# 11 has? Well this library lets you do just that! It will generate for you all the "magic types" that the C# compiler needs to "see" in order for it to allow using new language features even if you're not using the latest framework out there. |
| 10 | + |
| 11 | +Here's an example of some of the new features that **PolySharp** can enable downlevel: |
| 12 | + |
| 13 | + |
| 14 | + |
| 15 | +> **Note**: not all the new C# features can be "tricked" this way (eg. those requiring runtime support, such as [static abstract members](https://learn.microsoft.com/dotnet/csharp/whats-new/tutorials/static-virtual-interface-members), still won't work). But almost everything else will (eg. nullability annotations, pattern matching, etc.), and this applies to a big number of new C# features. Try **PolySharp** out, don't get stuck on C# 6.0 or other older versions! 🎉 |
| 16 | +
|
| 17 | +> **Note**: use on .NET Framework 3.5 is particularly limited due to shortcomings of the BCL there. In particular, the `System.Range` type will not be generated unless `System.ValueTuple` is referenced (meaning that eg. list patterns won't work by default), and some features such as records will not be usable at all due to the C# compiler missing some necessary APIs that cannot be polifilled. All other features should work as expected. |
| 18 | +
|
| 19 | +# Documentation 📖 |
| 20 | + |
| 21 | +**PolySharp** includes the following polyfills: |
| 22 | +- Nullability attributes (for [nullable reference types](https://learn.microsoft.com/dotnet/csharp/nullable-references)): |
| 23 | + - `[AllowNull]` |
| 24 | + - `[DisallowNull]` |
| 25 | + - `[DoesNotReturn]` |
| 26 | + - `[DoesNotReturnIf]` |
| 27 | + - `[MaybeNull]` |
| 28 | + - `[MaybeNullWhen]` |
| 29 | + - `[MemberNotNull]` |
| 30 | + - `[MemberNotNullWhen]` |
| 31 | + - `[NotNull]` |
| 32 | + - `[NotNullIfNotNull]` |
| 33 | + - `[NotNullWhen]` |
| 34 | +- `Index` and `Range` (see [indices and ranges](https://learn.microsoft.com/dotnet/csharp/whats-new/tutorials/ranges-indexes)) |
| 35 | +- `[UnscopedRef]` (see [low-level struct improvements](https://github.com/dotnet/csharplang/blob/main/proposals/low-level-struct-improvements.md)) |
| 36 | +- Required members (see [required modifier](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/required)) |
| 37 | + - `[RequiredMember]` |
| 38 | + - `[SetsRequiredMembers]` |
| 39 | +- `[CompilerFeatureRequired]` (needed to support several features) |
| 40 | +- `[IsExternalInit]` (needed for [init-only properties](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/init)) |
| 41 | +- `[SkipLocalsInit]` (see [docs](https://learn.microsoft.com/dotnet/csharp/language-reference/attributes/general#skiplocalsinit-attribute)) |
| 42 | +- Interpolated string handlers (see [docs](https://learn.microsoft.com/dotnet/csharp/whats-new/tutorials/interpolated-string-handler)) |
| 43 | + - `[InterpolatedStringHandler]` |
| 44 | + - `[InterpolatedStringHandlerArgument]` |
| 45 | +- `[CallerArgumentExpression]` (see [docs](https://learn.microsoft.com/dotnet/csharp/language-reference/proposals/csharp-10.0/caller-argument-expression)) |
| 46 | +- `[RequiresPreviewFeatures]` (needed for [preview features](https://github.com/dotnet/designs/blob/main/accepted/2021/preview-features/preview-features.md)) |
| 47 | +- `[AsyncMethodBuilder]` (needed for [custom method builder types](https://learn.microsoft.com/dotnet/csharp/language-reference/proposals/csharp-10.0/async-method-builders)) |
| 48 | +- `[StringSyntax]` (needed to enable [syntax highlight in the IDE](https://github.com/dotnet/runtime/issues/62505)) |
| 49 | +- `[ModuleInitializer]` (needed to enable [custom module initializers](https://learn.microsoft.com/dotnet/csharp/language-reference/proposals/csharp-9.0/module-initializers)) |
| 50 | + |
| 51 | +To leverage them, make sure to bump your C# language version. You can do this by setting the `<LangVersion>` MSBuild property in your project. For instance, by adding `<LangVersion>11.0</LangVersion>` (or your desired C# version) to the first `<PropertyGroup>` of your .csproj file. For more info on this, [see here](https://sergiopedri.medium.com/enabling-and-using-c-9-features-on-older-and-unsupported-runtimes-ce384d8debb), but remember that you don't need to manually copy polyfills anymore: simply adding a reference to **PolySharp** will do this for you automatically. |
| 52 | + |
| 53 | +It also includes the following optional runtime-supported polyfills: |
| 54 | +- Reflection annotation attributes (see [docs](https://learn.microsoft.com/dotnet/core/deploying/trimming/prepare-libraries-for-trimming)): |
| 55 | + - `[DynamicallyAccessedMembers]` |
| 56 | + - `[DynamicDependency]` |
| 57 | + - `[RequiresUnreferencedCode]` |
| 58 | + - `[UnconditionalSuppressMessage]` |
| 59 | +- `[StackTraceHidden]` (see [here](https://makolyte.com/csharp-exclude-exception-throw-helper-methods-from-the-stack-trace/)) |
| 60 | +- `[UnmanagedCallersOnly]` (see [docs](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.unmanagedcallersonlyattribute))) |
| 61 | +- Platform support annotation attributes (see [docs](https://learn.microsoft.com/dotnet/standard/analyzers/platform-compat-analyzer)): |
| 62 | + - `[ObsoletedOSPlatform]` |
| 63 | + - `[SupportedOSPlatform]` |
| 64 | + - `[SupportedOSPlatformGuard]` |
| 65 | + - `[TargetPlatform]` |
| 66 | + - `[UnsupportedOSPlatform]` |
| 67 | + - `[UnsupportedOSPlatformGuard]` |
| 68 | +- `[SuppressGCTransition]` (see [here](https://devblogs.microsoft.com/dotnet/improvements-in-native-code-interop-in-net-5-0/)) |
| 69 | + |
| 70 | +# Options ⚙️ |
| 71 | + |
| 72 | +**PolySharp**'s generation can be configured through some MSBuild properties to set in consuming projects. |
| 73 | + |
| 74 | +The following properties are available: |
| 75 | +- "PolySharpUsePublicAccessibilityForGeneratedTypes": makes all generated types public. |
| 76 | +- "PolySharpIncludeRuntimeSupportedAttributes": enables polyfills for (dummy) runtime-supported attributes too. |
| 77 | +- "PolySharpExcludeGeneratedTypes": excludes specific types from generation (';' or ',' separated type names). |
| 78 | +- "PolySharpIncludeGeneratedTypes": only includes specific types for generation (';' or ',' separated type names). |
0 commit comments