-
Notifications
You must be signed in to change notification settings - Fork 3
(sdks) Add new page on .NET/C# version compatibility #1393
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
28be1c3
c434383
ff1bb01
3264e14
6ae1e51
10c0414
71c4476
d1b8768
f7652a0
2a976a0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -65,6 +65,10 @@ exceptions: | |
| - XSS | ||
| - YAML | ||
| - ZIP | ||
| - SEO | ||
| - TLS | ||
| - BCL | ||
| - LLM | ||
| - MDX | ||
| - SEO | ||
| - AWS | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,270 @@ | ||
| --- | ||
| title: .NET Framework compatibility | ||
| description: Learn about supported .NET Framework versions (net462, net472, net48) and Unity compatibility for Fern-generated SDKs. | ||
| --- | ||
|
|
||
| Fern-generated .NET SDKs support older .NET Framework versions (`net462`, `net472`, `net48`) and Unity. | ||
|
||
|
|
||
| Because these SDKs are built with modern C# features, you'll need the following even when targeting older .NET Framework targets: | ||
| - A modern compiler (Visual Studio 2022 or .NET SDK) | ||
| - The appropriate .NET Framework Developer Pack or reference assemblies | ||
|
|
||
| ## Supported frameworks | ||
|
|
||
| | Target | Minimum Windows | Notes | | ||
| |--------|------------------|------------| | ||
| | **net462** | Windows 7 SP1 / Server 2008 R2 | Oldest supported for modern builds. Limited TLS support, older BCL. | | ||
| | **net472** | Windows 7 SP1 / Server 2008 R2 | Broad compatibility, supported for most enterprise apps. | | ||
| | **net48** | Windows 7 SP1 / Server 2008 R2 | Latest .NET Framework version with best long-term support. | | ||
|
||
|
|
||
| <Note> | ||
| The C# language version is determined by your compiler, while the target framework determines which runtime and base class library APIs are available. Fern SDKs use modern C# features but compile to older framework versions. | ||
| </Note> | ||
|
|
||
| <AccordionGroup> | ||
| <Accordion title="IDE compatibility"> | ||
| All major IDEs support Fern-generated SDKs when targeting `net462`, `net472`, and `net48` versions: | ||
|
|
||
| - **Visual Studio 2022** (recommended) - Works out of the box. Set `<LangVersion>` in your project and install the appropriate [developer pack](#developer-packs). | ||
| - **Visual Studio 2019** - Supports C# 9 natively. For newer C# versions, add the `Microsoft.Net.Compilers.Toolset` package. | ||
| - **Rider** - Uses Roslyn. Set `<LangVersion>` and ensure reference assemblies are available. | ||
| - **VS Code** - Works via OmniSharp and .NET SDK builds. | ||
| - **Unity** - Uses Unity's own C# compiler. See [Using SDKs with Unity](#using-sdks-with-unity). | ||
|
|
||
| <Info> | ||
| You can "bring your own compiler" with the `Microsoft.Net.Compilers.Toolset` package on any environment. | ||
| </Info> | ||
| </Accordion> | ||
| <Accordion title="Compiler compatibility"> | ||
|
|
||
| Use the **Roslyn compiler** (`csc`) that comes with Visual Studio 2022+ or the .NET SDK. Set your C# version via `<LangVersion>` to `latest`, `preview`, or a specific version (minimum `9`). | ||
|
|
||
| Fern's .NET SDK doesn't support the legacy Mono compiler (`mcs`, `gmcs`). Use Roslyn even when building on Mono. | ||
|
||
|
|
||
| <Info title="Building on Mono"> | ||
|
|
||
| Use the .NET SDK (`dotnet`) with the `Microsoft.NETFramework.ReferenceAssemblies` package to supply `net48` references on non-Windows. Use Roslyn via `dotnet build` or Mono's MSBuild. | ||
|
|
||
| ```bash title="macOS/Linux" | ||
| dotnet build -c Release | ||
| ``` | ||
| </Info> | ||
| </Accordion> | ||
| <Accordion title="Developer packs"> | ||
|
|
||
| - [.NET Framework 4.6.2 Developer Pack](https://dotnet.microsoft.com/en-us/download/dotnet-framework/net462) | ||
| - [.NET Framework 4.7.2 Developer Pack](https://dotnet.microsoft.com/en-us/download/dotnet-framework/net472) | ||
| - [.NET Framework 4.8 Developer Pack](https://dotnet.microsoft.com/en-us/download/dotnet-framework/net48) | ||
| </Accordion> | ||
| </AccordionGroup> | ||
|
|
||
| ## Using SDKs with Unity | ||
|
|
||
| Unity controls its own C# compiler and .NET profile, which affects how you use Fern's .NET SDK. | ||
|
|
||
| <AccordionGroup> | ||
| <Accordion title="C# language version"> | ||
| Unity compiles projects using Roslyn, typically supporting C# 9 (varies by Unity version). You can't force Unity to use a newer C# compiler by changing your package because Unity controls the compiler inside the Editor. | ||
| </Accordion> | ||
| <Accordion title="API compatibility level"> | ||
| Configure this in Unity: `Edit → Project Settings → Player → Other Settings → Api Compatibility Level` | ||
|
|
||
| - **.NET Standard 2.1** (recommended for cross-platform plugins) | ||
| - **.NET Framework 4.x** (Unity's "4.x equivalent" profile) | ||
|
|
||
| </Accordion> | ||
| <Accordion title="Required assemblies"> | ||
|
|
||
| Unity doesn't support NuGet packages, so you must manually download and add these assemblies to your Unity project: | ||
|
|
||
| | Assembly | NuGet Package | | ||
| |----------|---------------| | ||
| | Microsoft.Bcl.AsyncInterfaces | [10.0.0-preview.6.25358.103](https://www.nuget.org/packages/Microsoft.Bcl.AsyncInterfaces/10.0.0-preview.6.25358.103) | | ||
| | OneOf | [3.0.271](https://www.nuget.org/packages/OneOf/3.0.271) | | ||
| | OneOf.Extended | [3.0.271](https://www.nuget.org/packages/OneOf.Extended/3.0.271) | | ||
| | System.Buffers | [4.6.1](https://www.nuget.org/packages/System.Buffers/4.6.1) | | ||
| | System.IO.Pipelines | [10.0.0-preview.6.25358.103](https://www.nuget.org/packages/System.IO.Pipelines/10.0.0-preview.6.25358.103) | | ||
| | System.Memory | [4.6.3](https://www.nuget.org/packages/System.Memory/4.6.3) | | ||
| | System.Runtime.CompilerServices.Unsafe | [6.1.2](https://www.nuget.org/packages/System.Runtime.CompilerServices.Unsafe/6.1.2) | | ||
| | System.Text.Encodings.Web | [10.0.0-preview.6.25358.103](https://www.nuget.org/packages/System.Text.Encodings.Web/10.0.0-preview.6.25358.103) | | ||
| | System.Text.Json | [10.0.0-preview.6.25358.103](https://www.nuget.org/packages/System.Text.Json/10.0.0-preview.6.25358.103) | | ||
| | System.Threading.Tasks.Extensions | [4.6.3](https://www.nuget.org/packages/System.Threading.Tasks.Extensions/4.6.3) | | ||
| | portable.system.datetimeonly | [9.0.0](https://www.nuget.org/packages/portable.system.datetimeonly/9.0.0) | | ||
|
|
||
| </Accordion> | ||
| </AccordionGroup> | ||
|
|
||
| ## Project configuration examples | ||
|
|
||
| Use SDK-style projects where possible, as they provide modern compilers and simpler multi-targeting. If you have a classic project format, consider converting to SDK-style. The [legacy projects section](#legacy-projects) covers legacy setups that can't be converted. | ||
|
|
||
| <Note title="Building on macOS/Linux"> | ||
| When building for `net48` on macOS/Linux, you won't have the Windows targeting packs. Add the reference assemblies package: | ||
|
|
||
| ```xml title="YourProject.csproj" | ||
| <ItemGroup> | ||
| <PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" PrivateAssets="all" /> | ||
| </ItemGroup> | ||
| ``` | ||
| This provides the `net48` reference assemblies so Roslyn can compile for `net48` on any platform. You'll still need Mono or Wine to execute the result. | ||
| </Note> | ||
|
|
||
| <AccordionGroup> | ||
| <Accordion title="SDK-style projects (recommended)"> | ||
|
|
||
| Targeting `net48` with modern C# | ||
|
|
||
| <Steps> | ||
| <Step title="Configure your project"> | ||
|
|
||
| <Info title="Prerequisite (Windows)"> | ||
| Install the [.NET Framework 4.8 Developer Pack](#developer-packs) so the `net48` reference assemblies are available to the compiler. | ||
| </Info> | ||
|
|
||
| ```xml title="YourProject.csproj" | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
| <PropertyGroup> | ||
| <!-- Target .NET Framework 4.8 --> | ||
| <TargetFramework>net48</TargetFramework> | ||
|
|
||
| <!-- Use a modern C# version --> | ||
| <LangVersion>latest</LangVersion> | ||
|
|
||
| <!-- Optional, but recommended for better warnings --> | ||
| <Nullable>enable</Nullable> | ||
| </PropertyGroup> | ||
| </Project> | ||
| ``` | ||
| </Step> | ||
|
|
||
| <Step title="Build your project"> | ||
| ```bash | ||
| dotnet build -c Release | ||
| ``` | ||
| </Step> | ||
|
|
||
| <Step title="Multi-target (optional)"> | ||
| To support multiple frameworks, use `<TargetFrameworks>`: | ||
| {/* <!-- vale off --> */} | ||
| ```xml title="YourProject.csproj" | ||
| <TargetFrameworks>net48;net8.0</TargetFrameworks> | ||
| ``` | ||
| {/* <!-- vale on --> */} | ||
| </Step> | ||
| </Steps> | ||
| </Accordion> | ||
| <Accordion title="Legacy projects"> | ||
|
|
||
| For older MSBuild/Visual Studio versions, Visual Studio 2019, or legacy `packages.config` setups, add a modern Roslyn toolset and target the old framework. | ||
|
|
||
| <Steps> | ||
| <Step title="Install target packs"> | ||
| Install the appropriate [.NET Framework Developer Pack](#developer-packs) so Visual Studio can find the reference assemblies. | ||
| </Step> | ||
|
|
||
| <Step title="Set language version"> | ||
| ```xml title="YourProject.csproj" | ||
| <PropertyGroup> | ||
| <!-- Unlock modern C# --> | ||
| <LangVersion>latest</LangVersion> | ||
| </PropertyGroup> | ||
| ``` | ||
| Or use a specific version: `9`, `10`, `11`, `12`, or `preview`. | ||
| </Step> | ||
| <Step title="Add modern compiler"> | ||
|
|
||
| ```xml title="YourProject.csproj" | ||
| <ItemGroup> | ||
| <PackageReference Include="Microsoft.Net.Compilers.Toolset" Version="x.y.z"> | ||
| <!-- Keep it private: --> | ||
| <PrivateAssets>all</PrivateAssets> | ||
| </PackageReference> | ||
| </ItemGroup> | ||
| ``` | ||
| This ensures your build uses a modern `csc.exe` even if your IDE/MSBuild is older. | ||
|
|
||
| </Step> | ||
| </Steps> | ||
| </Accordion> | ||
| </AccordionGroup> | ||
|
|
||
| ## Distribution | ||
|
||
|
|
||
| <AccordionGroup> | ||
| <Accordion title="Multi-target pack for NuGet"> | ||
| A common configuration for broad compatibility across multiple .NET versions: | ||
|
|
||
| {/* <!-- vale off --> */} | ||
| ```xml title="YourProject.csproj" | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
| <PropertyGroup> | ||
| <TargetFrameworks>net48;net6.0;net8.0</TargetFrameworks> | ||
| <LangVersion>latest</LangVersion> | ||
| <Nullable>enable</Nullable> | ||
| <GeneratePackageOnBuild>true</GeneratePackageOnBuild> | ||
| <PackageId>Your.Package.Id</PackageId> | ||
| <Version>1.2.3</Version> | ||
| <Authors>Your Team</Authors> | ||
| <Description>Your description</Description> | ||
| </PropertyGroup> | ||
|
|
||
| <!-- Cross-platform net48 builds --> | ||
| <ItemGroup> | ||
| <PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" PrivateAssets="all" /> | ||
| </ItemGroup> | ||
| </Project> | ||
| ``` | ||
| {/* <!-- vale on --> */} | ||
|
|
||
| Build and pack: | ||
|
|
||
| ```bash | ||
| dotnet pack -c Release | ||
| ``` | ||
| </Accordion> | ||
| <Accordion title="CI/CD configuration"> | ||
| Force a specific C# version in your build pipeline: | ||
| ```bash | ||
| dotnet build -c Release /p:LangVersion=11 | ||
| ``` | ||
| </Accordion> | ||
| </AccordionGroup> | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| <AccordionGroup> | ||
| <Accordion title="Type or namespace IsExternalInit not found"> | ||
| Add a small shim in your project or reference a helper package. | ||
| </Accordion> | ||
| <Accordion title="Reference assemblies for .NETFramework,Version=v4.8 were not found"> | ||
| - Windows: install the [.NET Framework 4.8 Developer Pack](#developer-packs). | ||
| - Cross-platform/CI: add `Microsoft.NETFramework.ReferenceAssemblies` to the project (as `PrivateAssets=all`). | ||
| </Accordion> | ||
| <Accordion title="VS 2019 can't parse newer syntax"> | ||
| Add `Microsoft.Net.Compilers.Toolset` to the project, or move to VS 2022+. | ||
| </Accordion> | ||
| <Accordion title="CS0619: Constructors of types with required members are not supported"> | ||
| This error occurs when using the `required` keyword with older Visual Studio versions. Follow the instructions at [Legacy projects](#legacy-projects) to add a modern compiler. | ||
|
|
||
| <Note> | ||
| Some versions of Visual Studio may show this error in the IDE but compile the project successfully when using the package-provided compiler. | ||
| </Note> | ||
| </Accordion> | ||
| <Accordion title="C# language feature workarounds"> | ||
|
|
||
| Most modern C# features work on `net462`, `net472`, and `net48`, but a few require workarounds: | ||
|
|
||
| - **`init` accessors** – Requires the `System.Runtime.CompilerServices.IsExternalInit` type. Add a small shim in your project or reference a helper package. | ||
|
||
| - **Records** - Work out of the box (compiler-generated IL), but may need the same `IsExternalInit` shim. | ||
| - **Nullable annotations** - Purely compile-time, work without modification. | ||
| </Accordion> | ||
| </AccordionGroup> | ||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's shorten it to

.NET compatibility, it looks a little awkward