【C#】古い環境向けでもなるべく最新で書く
ライブラリはnugetで探す
新しく追加された公式APIは、ライブラリとしても公開されている事が多い。
たとえばTimeProvider
は.NET8以降だが、
nugetで追加ライブラリとしても公開されていて、
対応バージョンが「.NET Standard 2.0」や「.NET Framework 4.6.2」の古い環境でも使える。
- .NET 8
- .NET Standard 2.0
- .NET Framework 4.6.2
APIリファレンス(MS learn)にはこのことが書かれてないので注意。
対応バージョンだけで判断してはいけない。
MSが公式に出している事が多いのでMicrosoft.~
で始まる名前で調べると出たりする
Microsoft.Bcl.~
.NET Standard2.0でも使える新しめのAPI
追加ver: .NET 8 ~
FrozenDictionary<T>
/ FrozenSet<T>
TimeProvider
Microsoft.Bcl.TimeProvider
XxHash3
/ XxHash128
System.IO.Hashing
追加ver: .NET Core 2.1 / .NET Standard 2.1~
Span<T>
/ Memory<T>
System.Memory
System.Span
System.ReadOnlySpan
System.Memory
System.ReadOnlyMemory
System.Buffers.MemoryPool
System.Buffers.ReadOnlySequence
System.Buffers.Text.Utf8Parser
System.Buffers.Text.Utf8Formatter
ArrayPool<T>
System.Buffers
(C#) ArrayPool<T>.Shared 解体新書 - ネコのために鐘は鳴る
System.IO.Pipelines
System.IO.Pipelines.Pipe
System.IO.Pipelines.PipeWriter
System.IO.Pipelines.PipeReader
IAsyncEnumerable<T>
/ IAsyncEnumerator<T>
/ IAsyncDisposable<T>
await using
が使えるようになる
Microsoft.Bcl.AsyncInterfaces
IAsyncEnumerable<T>
IAsyncEnumerator<T>
IAsyncDisposable<T>
StopWatch.GetElapesedTime
→ MS.Bcl.TimeProvider
の TimeProvider.System.GetElapesedTime
最新のSDKで古い環境向けに出力設定する
TargetFramework(s)
csprojのTargetFramework
で古いverを指定すれば出力できる。
最新.NET SDKで.NET Framework ランタイム向けに書き出せる。
大抵は、.NET Starndard 2.0を指定しておけば大体は大丈夫。
<TargetFramework>netstandard2.0</TargetFramework>
ライブラリとかで古い環境向けと最新向けどちらも出しておくのはTargetFrameworksを指定する。
<TargetFrameworks>netstandard2.0;net8</TargetFrameworks>
こうしておくと互換性をもったまま、新しい環境だと最適化とかが効いて高速・省メモリにできたりする。
LangVersion
LangVersion
をlatest
にすれば使っているSDKが対応する最新のC#の言語バージョンが使える。
<LangVersion>latest</LangVersion>
使えると言っても公式そのままでは公式APIが無いとかで実際にはコンパイルエラー・ランタイムエラーになるので注意。
- 公式APIは別ライブラリとしてnuget公開されてる場合は導入する
- polyfillを使うことで解決するものもある
- ランタイム対応が必要なものは辛い
.NET9.0以降は、latestは非推奨になるらしい
ポリフィル(polyfill)
C#界隈だとあまり活用されてないけど、JS/Pythonとかだとよくあるメジャーな手法。
(特にエンジンがバラバラに実装されるJS)
コンパイルエラーに関してはpolyfillのライブラリを導入することで使えるようになるものがある。
有名なのは「PolySharp」
対応リストはこの辺
PolySharpだけで上手くいかないのはnugetで追加導入;
-
Index
/Range
- ※publicなメンバーの型などで使うときに必要
- → IndexRange