UfcppSample
UfcppSample copied to clipboard
新機能の実装方法(modreq + RuntimeFeature)
以下の辺りをまとめて「新機能の実装方法」みたいなページを1つ作ってもいいかも
話の流れ:
- C# は C# コード → (C# コンパイラー) → IL → (JIT コンパイラー/.NET Runtime) → ネイティブ コード って処理をしてる関係で、新機能を実装する際に以下の2パターンあり得る
- C# コンパイラーだけでできる仕事(実装が楽、古い環境でも動かしやすい)
- .NET Runtime 側の修正がいるもの(大変、最新環境でないと動かない)
- C# だけでできるものにも3パターン
- 元々 .NET Runtime は持ってたけど C# では使ってなかったものを解放
- 本当に構文糖衣で、頑張れば同様のコードを古いコンパイラーでも書ける
- 古いコンパイラーに掛けられたらまずいものを ModReq で制限
- .NET Runtime でやるものの場合、ターゲットで動くかどうかのフラグが必要 → RuntimeFeature
書く場所:
- 「その他」の最後、「パターン ベースな構文」の次辺りが筆頭候補
- 「C#の言語バージョンと.NETバージョン」とかからもリンク
ModReq
mod (custom modifier)は、属性と似た仕組みだけど、フィールドとかプロパティじゃなくて、型の方に付くものらしい。
modopt と modreq があって、optional (わからなかったら無視していい)か required (解釈が必須。わからない場合その型を使っているものに触れてはいけない)かの差。
C# ではほとんど使ってこなかったんだけど、C# 7.2 くらいから modreq を使い始めてる。 (元々は Managed C++ で volatile 引数とか const メソッドとかのために使ってたみたい。)
mod (型に付く修飾)を期待してるわけじゃなくて、req (わからない場合触れてはいけない)の方に期待してるみたい。
in 引数とか unmanaged 制約とか、正しく解釈できない古いバージョンのコンパイラーから触られるとまずいものに付けて運用してる。
C# 9.0 では、initonly (プロパティの init アクセサ―)に modreq を付ける運用するみたいなので、この機に modreq の話を足したい。
というか、7.2、8.0 の時にちらほら見かける単語だなと思ってたけどあまりにも情報がなくて。 やっと調べがついたのでこの機に。
https://github.com/ufcpp/UfcppSample/issues/297#issuecomment-792225924 init-only プロパティの項目に modreq については別途説明予定との記載あり。
CompilerFeatureRequiredAttribute (modreq を使えないところがあったり、modreq を出しちゃうとバイナリ互換壊しかねない場所で、普通に属性でやるとか言ってる) runtime/issues/66167