A01_fieldキーワード
今回はC# 14で追加された field キーワードについて解説します。field キーワードとは、自動実装プロパティにロジックを書きたいときに、これまで必要だった private 変数(バッキングフィールド)を書かずに済むようにする機能です。
事前準備
Visual Studio 2026 を起動します。まだインストールしていない場合は、先にインストールしてください。
「新しいプロジェクトの作成」から「Windows フォーム アプリ」を選択します。この際、.NET Framework 版ではない方を選んでください。プロジェクト名は任意のもので構いません。ターゲットフレームワークは .NET 10 を選択し、プロジェクトを作成します。
自動実装プロパティを作成する
Form1 のコードの下に Product クラスを作成し、ProductId と ProductName の自動実装プロパティを定義します。
public class Product
{
public int ProductId { get; set; }
public string ProductName { get; set; } = "";
}
画面側で Product を new し、ProductId と ProductName に値を設定して実行すると、それぞれ設定した値がそのまま入っていることが確認できます。
ProductId・ProductName に値を設定して実行する
プロパティにロジックを入れる(従来の書き方)
例えば ProductId にマイナス値を入れられないようにしたい場合、これまでは private 変数を同じ型で用意し、get ではその変数をそのまま返却、set では値をチェックして private 変数に代入する、というロジックを書く必要がありました。
private int _productId = 123;
public int ProductId
{
get => _productId;
set
{
if (value < 0)
{
_productId = 0;
return;
}
_productId = value;
}
}
この状態で実行し、-1 を設定すると 0 にクランプされ、123 を設定するとそのまま 123 になることを確認できます。private 変数を宣言し、設定された値をチェックするロジックを書くのが定番のやり方でした。
-1 を設定すると 0 にクランプされる
field キーワードで書き換える
このお決まりの private 変数を書かなくてよくなるのが field キーワードです。get・set の中で、これまで _productId と書いていた箇所を field と書くだけで、同じ役目を果たしてくれます。
get の _productId を field に置き換える
private 変数の宣言自体が不要になり、プロパティの中だけで完結する形になります。
public int ProductId
{
get => field;
set
{
if (value < 0)
{
field = 0;
return;
}
field = value;
}
}
private 変数の宣言が不要になった
この時点では初期値を入れていないため、設定前・設定後ともに 0 と表示されますが、ロジック自体はきちんと動作しています。
初期値を設定する
初期値を入れたい場合は、プロパティの最後(閉じ括弧の後ろ)に = で値を指定します。もしくはコンストラクターで設定しても構いません。
プロパティの末尾に初期値を指定する
public int ProductId
{
get => field;
set
{
if (value < 0)
{
field = 0;
return;
}
field = value;
}
} = 123;
これで実行すると、設定前は 123、設定後は 0 となり、ロジックがきちんと効いていることが確認できます。
field キーワードが使える場所の制約
注意点として、field キーワードは get と set の中でしか使えません。コンストラクターやメソッドなど、それ以外の場所で使おうとしてもコンパイルエラーになるため、その場合は通常どおりプロパティ名でアクセスする必要があります。
例えば ProductId と ProductName を連結して返す GetString メソッドを書く場合、field ではなくプロパティ名を使います。
public string GetString()
{
return ProductId + ":" + ProductName;
}
これまではバッキングフィールド(_productId)を使うのか、プロパティ名(ProductId)を使うのかが曖昧になりがちでしたが、field キーワードを使うとプロパティ名でしかアクセスできなくなるため、内部的にもカプセル化が強まります。
カプセル化の強さを比較する
従来の private 変数(バッキングフィールド)方式では、クラス内部のどこからでも _productId に直接アクセスできてしまうため、set のロジックを経由せずに値を書き換えることができてしまいます。例えば GetString メソッドの中で、あえて _productId にマイナス値を代入してみます。
GetString 内で _productId に直接マイナス値を代入できてしまう
public string GetString()
{
_productId = -123;
return ProductId + ":" + ProductName;
}
この状態で実行すると「-123:AAA」と表示され、set のロジックを通らずにマイナス値が入り込んでしまいます。バグとしてこのような書き方をすることは通常ありませんが、書こうと思えば書けてしまう、つまりバグが入り込む余地があるということです。
field キーワードを使った場合は、このような抜け道自体が存在しません。プロパティを通してしか値を変更できないため、必ず set のロジックを経由することが保証されます。
field キーワードによりプロパティ経由でしか値を変更できない
まとめ
基本的には自動実装プロパティを使い、ロジックを入れたくなったときは field キーワードを使ってアクセスする、という書き方をしていくのがよいでしょう。今後は積極的に field キーワードを使い、内部的にもカプセル化してしまう書き方がおすすめです。
Udemyでの動画版はこちらからご覧いただけます
00_はじめに
01_VisualStudio2026をインストールしてください
A01_fieldキーワード
B01_extensionブロックとは
B02_拡張メソッドとは
B03_extensionブロック
B04_型パラメータありの拡張メソッド
B05_型パラメータありのextensionブロックの書き方
B06_拡張プロパティ
B07_拡張静的プロパティ&メソッド
B08_拡張演算子
C01_partialコンストラクター
C02_幽霊コードを定義パーツで契約による実装をするという考え方
C03_partialイベント
D01_Null条件付き代入
E01_複合代入演算子のオーバーロード
F01_明示的な型を指定せずにラムダパラメータでパラメータ修飾子を使用する
G01_nameofはバインドされていないジェネリック型をサポートします
H01_SpanTおよびReadOnlySpanTのより暗黙的な変換
Udemyでの動画版はこちらからご覧いただけます