バッキングフィールドを持つ完全なプロパティ
getterとsetterにロジックを追加します。
「バッキングフィールドを持つ完全なプロパティ」はCoddyKit上の無料C# Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC# Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C# Academyコースには全4レッスンが含まれています。
自動実装プロパティの先へ
get や set の内部にロジックが必要な場合は、明示的なバッキングフィールドを持つ完全なプロパティを記述します。フィールドがデータを保存し、アクセサーがアクセスを制御します。
using System;
class Temperature
{
private double _celsius;
public double Celsius
{
get { return _celsius; }
set { _celsius = value; }
}
}
class Program
{
static void Main()
{
var t = new Temperature();
t.Celsius = 21.5;
Console.WriteLine(t.Celsius);
}
}バッキングフィールドの命名規則
慣例では、バッキングフィールドは private にし、_name のように先頭にアンダースコアを付けて命名します。パブリックプロパティがそれを公開します。
using System;
class Person
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
}
class Program
{
static void Main()
{
var p = new Person();
p.Name = "Grace";
Console.WriteLine(p.Name);
}
}value キーワード
set アクセサー内では、暗黙的なパラメーター value に代入される値が格納されます。その値をどう扱うかは自分で決められます。
using System;
class Box
{
private int _size;
public int Size
{
get { return _size; }
set { _size = value * 2; }
}
}
class Program
{
static void Main()
{
var box = new Box();
box.Size = 10;
Console.WriteLine("Stored size: " + box.Size);
}
}setter での検証
完全なプロパティの一般的な用途は、入力を保存する前に検証することです。値が無効な場合は例外をスローします。
using System;
class Account
{
private decimal _balance;
public decimal Balance
{
get { return _balance; }
set
{
if (value < 0)
throw new ArgumentException("Balance cannot be negative");
_balance = value;
}
}
}
class Program
{
static void Main()
{
var a = new Account();
a.Balance = 500m;
Console.WriteLine("Balance: " + a.Balance);
}
}計算プロパティ(読み取り専用)
get だけを持つプロパティは、他のフィールドから値を計算できます。何も保存しないため、バッキングフィールドはありません。
using System;
class Rectangle
{
private double _width;
private double _height;
public Rectangle(double w, double h)
{
_width = w;
_height = h;
}
public double Area
{
get { return _width * _height; }
}
}
class Program
{
static void Main()
{
var r = new Rectangle(4, 5);
Console.WriteLine("Area: " + r.Area);
}
}setter の副作用
setter は値を保存するだけでなく、入力の正規化、関連する状態の更新、変更のログ記録なども行えます。
using System;
class User
{
private string _email;
public string Email
{
get { return _email; }
set { _email = value.Trim().ToLower(); }
}
}
class Program
{
static void Main()
{
var u = new User();
u.Email = " Hello@Example.COM ";
Console.WriteLine("Normalized: " + u.Email);
}
}getter での遅延計算
getter は、初めて要求されたときに、コストの高い計算結果をバッキングフィールドにキャッシュできます。
using System;
class Report
{
private string _cached;
public string Content
{
get
{
if (_cached == null)
_cached = "Generated at runtime";
return _cached;
}
}
}
class Program
{
static void Main()
{
var r = new Report();
Console.WriteLine(r.Content);
Console.WriteLine(r.Content);
}
}不正な状態の防止
バッキングフィールドとロジックを組み合わせると、オブジェクトを常に有効な状態に保てます。ここでは setter が値を範囲内に収めています。
using System;
class Volume
{
private int _level;
public int Level
{
get { return _level; }
set
{
if (value < 0) _level = 0;
else if (value > 100) _level = 100;
else _level = value;
}
}
}
class Program
{
static void Main()
{
var v = new Volume();
v.Level = 150;
Console.WriteLine("Clamped: " + v.Level);
}
}保存値と計算値の組み合わせ
クラスでは、保存されたプロパティ(バッキングフィールドを持つもの)と、それらから導出される読み取り専用の計算プロパティを組み合わせることがよくあります。
using System;
class Employee
{
private string _first;
private string _last;
public string First { get { return _first; } set { _first = value; } }
public string Last { get { return _last; } set { _last = value; } }
public string FullName { get { return _first + " " + _last; } }
}
class Program
{
static void Main()
{
var e = new Employee { First = "Marie", Last = "Curie" };
Console.WriteLine(e.FullName);
}
}変更通知の発行
setter はデータが変更されたことを通知するのに適した場所であり、UI フレームワークで頻繁に使われるパターンです。
using System;
class Model
{
private int _count;
public int Count
{
get { return _count; }
set
{
if (_count != value)
{
_count = value;
Console.WriteLine("Count changed to " + _count);
}
}
}
}
class Program
{
static void Main()
{
var m = new Model();
m.Count = 1;
m.Count = 1;
m.Count = 2;
}
}全体を組み立てる
完全なプロパティを使うと、クラスで不変条件を維持したり、派生データを公開したりしながら、フィールドのように扱えるすっきりしたインターフェイスを提供できます。
using System;
class Thermostat
{
private double _target;
public double Target
{
get { return _target; }
set { _target = value < 10 ? 10 : value; }
}
public string Status { get { return _target >= 22 ? "Warm" : "Cool"; } }
}
class Program
{
static void Main()
{
var th = new Thermostat();
th.Target = 5;
Console.WriteLine(th.Target + " -> " + th.Status);
th.Target = 24;
Console.WriteLine(th.Target + " -> " + th.Status);
}
}理解度チェック
完全なプロパティについて理解できているか確認しましょう。
まとめ
完全なプロパティは、private なバッキングフィールドと明示的な get/set アクセサーを組み合わせたものです。これにより、検証、正規化、キャッシュ、変更通知などを追加できます。読み取り専用の計算プロパティは getter だけを持ち、バッキングフィールドはありません。setter では value キーワードに代入される値が渡されます。
using System;
class Demo
{
private int _n;
public int N
{
get { return _n; }
set { _n = value < 0 ? 0 : value; }
}
public int Doubled { get { return _n * 2; } }
}
class Program
{
static void Main()
{
var d = new Demo();
d.N = -5;
Console.WriteLine(d.N + ", " + d.Doubled);
}
}よくある質問
「バッキングフィールドを持つ完全なプロパティ」レッスンは無料ですか?
はい。「バッキングフィールドを持つ完全なプロパティ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C# Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C# Academyコースには全4レッスンが含まれています。
「バッキングフィールドを持つ完全なプロパティ」で何を学びますか?
getterとsetterにロジックを追加します。 ブラウザで直接実行するハンズオンコードでC# Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
C# Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのC# Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「バッキングフィールドを持つ完全なプロパティ」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このC# Academyレッスンでコードを書いて実行できますか?
はい。すべてのC# Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。