Skip to content

Commit c8e558d

Browse files
authored
(sdks) Add new page on .NET/C# version compatibility (#1393)
1 parent 0ba5859 commit c8e558d

File tree

5 files changed

+238
-0
lines changed

5 files changed

+238
-0
lines changed

.vale.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Microsoft.Accessibility = NO
1919
Microsoft.Passive = NO
2020
Microsoft.Suspended = NO
2121
Microsoft.Vocab = NO
22+
Microsoft.Spacing = NO
2223
Microsoft.Semicolon = NO # Mostly just picks up code
2324
Microsoft.SentenceLength = NO # Mostly just picks up code
2425
Microsoft.Dashes = NO

.vale/styles/FernStyles/Acronyms.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ exceptions:
6565
- XSS
6666
- YAML
6767
- ZIP
68+
- SEO
69+
- TLS
70+
- BCL
71+
- LLM
6872
- MDX
6973
- SEO
7074
- AWS

.vale/styles/FernStyles/Headings.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ exceptions:
2727
- Support
2828
- Markdown
2929
- Docs
30+
- Mono
31+
- Unity
32+
- SDK
33+
- SDKs
3034
- API Reference
3135
- API Explorer
3236
- GitHub
Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
---
2+
title: .NET compatibility
3+
description: Learn about supported .NET Framework versions (net462, net472, net48) and Unity compatibility for Fern-generated SDKs.
4+
---
5+
6+
Fern-generated .NET SDKs support modern .NET versions, .NET Framework versions, and Unity.
7+
8+
Because these SDKs are built with modern C# features, you'll need the following even when targeting older .NET Framework targets:
9+
- A modern compiler (Visual Studio 2022 or .NET SDK)
10+
- The appropriate .NET Framework Developer Pack or reference assemblies
11+
12+
## Supported frameworks
13+
14+
Fern .NET SDKs support [all officially supported .NET versions](https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-framework), except for net35.
15+
16+
| Framework | Target Framework Moniker (TFM) |
17+
|--------|----------|
18+
| .NET 9 | net9.0 |
19+
| .NET 8 | net8.0 |
20+
| .NET Framework 4.8.1 | net481 |
21+
| .NET Framework 4.8 | net48 |
22+
| .NET Framework 4.7.2 | net472 |
23+
| .NET Framework 4.7.1 | net471 |
24+
| .NET Framework 4.7 | net47 |
25+
| .NET Framework 4.6.2 | net462 |
26+
27+
<Note>
28+
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.
29+
</Note>
30+
31+
<AccordionGroup>
32+
<Accordion title="IDE compatibility">
33+
All major IDEs support Fern-generated SDKs when targeting `net462`, `net472`, and `net48` versions:
34+
35+
- **Visual Studio 2022** (recommended) - Works out of the box. Set `<LangVersion>` in your project and install the appropriate [developer pack](#developer-packs).
36+
- **Visual Studio 2019** - Supports C# 9 natively. For newer C# versions, add the `Microsoft.Net.Compilers.Toolset` package.
37+
- **Rider** - Uses Roslyn. Set `<LangVersion>` and ensure reference assemblies are available.
38+
- **VS Code** - Works via OmniSharp and .NET SDK builds.
39+
- **Unity** - Uses Unity's own C# compiler. See [Using SDKs with Unity](#using-sdks-with-unity).
40+
41+
<Info>
42+
You can "bring your own compiler" with the `Microsoft.Net.Compilers.Toolset` package on any environment.
43+
</Info>
44+
</Accordion>
45+
<Accordion title="Compiler compatibility">
46+
47+
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`).
48+
49+
Fern's .NET SDK doesn't support the legacy Mono compiler (`mcs`, `gmcs`) or the pre-Roslyn `csc.exe` compiler. Use Roslyn even when building on Mono.
50+
51+
<Info title="Building on Mono">
52+
53+
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.
54+
55+
```bash title="macOS/Linux"
56+
dotnet build -c Release
57+
```
58+
</Info>
59+
</Accordion>
60+
<Accordion title="Developer packs">
61+
62+
- [.NET Framework 4.6.2 Developer Pack](https://dotnet.microsoft.com/en-us/download/dotnet-framework/net462)
63+
- [.NET Framework 4.7.2 Developer Pack](https://dotnet.microsoft.com/en-us/download/dotnet-framework/net472)
64+
- [.NET Framework 4.8 Developer Pack](https://dotnet.microsoft.com/en-us/download/dotnet-framework/net48)
65+
</Accordion>
66+
</AccordionGroup>
67+
68+
## Using SDKs with Unity
69+
70+
Unity controls its own C# compiler and .NET profile, which affects how you use Fern's .NET SDK.
71+
72+
<AccordionGroup>
73+
<Accordion title="C# language version">
74+
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.
75+
</Accordion>
76+
<Accordion title="API compatibility level">
77+
Configure this in Unity: `Edit → Project Settings → Player → Other Settings → Api Compatibility Level`
78+
79+
- **.NET Standard 2.1** (recommended for cross-platform plugins)
80+
- **.NET Framework 4.x** (Unity's "4.x equivalent" profile)
81+
82+
</Accordion>
83+
<Accordion title="Required assemblies">
84+
85+
Unity doesn't support NuGet packages, so you must manually download and add these assemblies to your Unity project:
86+
87+
| Assembly | NuGet Package |
88+
|----------|---------------|
89+
| 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) |
90+
| OneOf | [3.0.271](https://www.nuget.org/packages/OneOf/3.0.271) |
91+
| OneOf.Extended | [3.0.271](https://www.nuget.org/packages/OneOf.Extended/3.0.271) |
92+
| System.Buffers | [4.6.1](https://www.nuget.org/packages/System.Buffers/4.6.1) |
93+
| 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) |
94+
| System.Memory | [4.6.3](https://www.nuget.org/packages/System.Memory/4.6.3) |
95+
| System.Runtime.CompilerServices.Unsafe | [6.1.2](https://www.nuget.org/packages/System.Runtime.CompilerServices.Unsafe/6.1.2) |
96+
| 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) |
97+
| 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) |
98+
| System.Threading.Tasks.Extensions | [4.6.3](https://www.nuget.org/packages/System.Threading.Tasks.Extensions/4.6.3) |
99+
| portable.system.datetimeonly | [9.0.0](https://www.nuget.org/packages/portable.system.datetimeonly/9.0.0) |
100+
101+
</Accordion>
102+
</AccordionGroup>
103+
104+
## Project configuration examples
105+
106+
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.
107+
108+
<Note title="Building on macOS/Linux">
109+
When building for `net48` on macOS/Linux, you won't have the Windows targeting packs. Add the reference assemblies package:
110+
111+
```xml title="YourProject.csproj"
112+
<ItemGroup>
113+
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" PrivateAssets="all" />
114+
</ItemGroup>
115+
```
116+
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.
117+
</Note>
118+
119+
<AccordionGroup>
120+
<Accordion title="SDK-style projects (recommended)">
121+
122+
Targeting `net48` with modern C#
123+
124+
<Steps>
125+
<Step title="Configure your project">
126+
127+
<Info title="Prerequisite (Windows)">
128+
Install the [.NET Framework 4.8 Developer Pack](#developer-packs) so the `net48` reference assemblies are available to the compiler.
129+
</Info>
130+
131+
```xml title="YourProject.csproj"
132+
<Project Sdk="Microsoft.NET.Sdk">
133+
<PropertyGroup>
134+
<!-- Target .NET Framework 4.8 -->
135+
<TargetFramework>net48</TargetFramework>
136+
137+
<!-- Use a modern C# version -->
138+
<LangVersion>latest</LangVersion>
139+
140+
<!-- Optional, but recommended for better warnings -->
141+
<Nullable>enable</Nullable>
142+
</PropertyGroup>
143+
</Project>
144+
```
145+
</Step>
146+
147+
<Step title="Build your project">
148+
```bash
149+
dotnet build -c Release
150+
```
151+
</Step>
152+
153+
<Step title="Multi-target (optional)">
154+
To support multiple frameworks, use `<TargetFrameworks>`:
155+
{/* <!-- vale off --> */}
156+
```xml title="YourProject.csproj"
157+
<TargetFrameworks>net48;net8.0</TargetFrameworks>
158+
```
159+
{/* <!-- vale on --> */}
160+
</Step>
161+
</Steps>
162+
</Accordion>
163+
<Accordion title="Legacy projects">
164+
165+
For older MSBuild/Visual Studio versions, Visual Studio 2019, or legacy `packages.config` setups, add a modern Roslyn toolset and target the old framework.
166+
167+
<Steps>
168+
<Step title="Install target packs">
169+
Install the appropriate [.NET Framework Developer Pack](#developer-packs) so Visual Studio can find the reference assemblies.
170+
</Step>
171+
172+
<Step title="Set language version">
173+
```xml title="YourProject.csproj"
174+
<PropertyGroup>
175+
<!-- Unlock modern C# -->
176+
<LangVersion>latest</LangVersion>
177+
</PropertyGroup>
178+
```
179+
Or use a specific version: `9`, `10`, `11`, `12`, or `preview`.
180+
</Step>
181+
<Step title="Add modern compiler">
182+
183+
```xml title="YourProject.csproj"
184+
<ItemGroup>
185+
<PackageReference Include="Microsoft.Net.Compilers.Toolset" Version="x.y.z">
186+
<!-- Keep it private: -->
187+
<PrivateAssets>all</PrivateAssets>
188+
</PackageReference>
189+
</ItemGroup>
190+
```
191+
This ensures your build uses a modern `csc.exe` even if your IDE/MSBuild is older.
192+
193+
</Step>
194+
</Steps>
195+
</Accordion>
196+
</AccordionGroup>
197+
198+
## Troubleshooting
199+
200+
<AccordionGroup>
201+
<Accordion title="Type or namespace IsExternalInit not found">
202+
Add a small shim in your project or reference a helper package.
203+
</Accordion>
204+
<Accordion title="Reference assemblies for .NETFramework,Version=v4.8 were not found">
205+
- Windows: install the [.NET Framework 4.8 Developer Pack](#developer-packs).
206+
- Cross-platform/CI: add `Microsoft.NETFramework.ReferenceAssemblies` to the project (as `PrivateAssets=all`).
207+
</Accordion>
208+
<Accordion title="VS 2019 can't parse newer syntax">
209+
Add `Microsoft.Net.Compilers.Toolset` to the project, or move to VS 2022+.
210+
</Accordion>
211+
<Accordion title="CS0619: Constructors of types with required members are not supported">
212+
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.
213+
214+
<Note>
215+
Some versions of Visual Studio may show this error in the IDE but compile the project successfully when using the package-provided compiler.
216+
</Note>
217+
</Accordion>
218+
</AccordionGroup>
219+
220+
221+
222+
223+
224+
225+
226+
227+

fern/products/sdks/sdks.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ navigation:
130130
- page: Publishing to NuGet
131131
path: ./overview/csharp/publishing-to-nuget.mdx
132132
slug: publishing
133+
- page: Version compatibility
134+
path: ./overview/csharp/version-compatibility.mdx
133135
- page: Adding custom code
134136
hidden: true
135137
path: ./overview/csharp/custom-code.mdx

0 commit comments

Comments
 (0)