読み取り専用・書き込み専用プロパティ
CoddyのC#ジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 11/70。
読み取り専用、または書き込み専用のプロパティが必要になることがあります。個別のアクセサに private を使用することで、これを制御できます。
読み取り専用プロパティは、パブリックなゲッターを持ちますが、プライベートなセッターを持つ(またはセッターを全く持たない)ものです:
public class User
{
public string Username { get; private set; }
public User(string username)
{
Username = username;
}
}外部のコードは Username を読み取ることができますが、クラス自身のみがそれを変更できます。これは、コンストラクト中に一度だけ設定されるべき値に便利です。
書き込み専用プロパティは、パブリックなセッターを持ちますが、ゲッターはプライベートです:
public class Account
{
public string Password { private get; set; }
public bool ValidatePassword(string input)
{
return input == Password;
}
}書き込み専用プロパティは稀ですが、パスワードのような機密データには便利です。保存された値を公開せずに入力を受け付けたい場合に適しています。
ゲッターのみを使用して、真の読み取り専用プロパティを作成することもできます。
public class Circle
{
public double Radius { get; }
public double Area => Math.PI * Radius * Radius;
public Circle(double radius)
{
Radius = radius;
}
}get; のみのプロパティは、コンストラクタ内または宣言時にのみ割り当てることができ、オブジェクト作成後は不変になります。
チャレンジ
簡単機密データを保護するために、読み取り専用プロパティと書き込み専用プロパティをいつ使用するかを示す、安全な設定システムを構築しましょう。
コードを整理するために2つのファイルを作成します:
Config.cs:Settings名前空間内に、サーバー設定を管理するServerConfigクラスを定義します。以下の要素を持つ必要があります:- 読み取り専用プロパティ
ServerName(コンストラクタでのみ設定可能) - プライベートセッターを持つ読み取り専用プロパティ
Port(コンストラクタ経由で設定) - 秘密キーを内部的に保存する書き込み専用プロパティ
ApiKey - 提供されたキーが保存されているものと一致する場合に
trueを返すメソッドValidateApiKey(string key) - サーバー名とポートを受け取るコンストラクタ
- 読み取り専用プロパティ
Program.cs: メインファイルで、入力値を使用してServerConfigオブジェクトを作成し、APIキーを設定してから、テスト用キーに対して検証を行います。
4つの入力を受け取ります:
- サーバー名
- ポート番号
- 保存するAPIキー
- 検証するAPIキー
サーバーの詳細と検証結果を次の形式で出力してください:
Server: {ServerName}, Port: {Port}
API Key Valid: {True/False}例えば、入力が MainServer、8080、secret123、secret123 の場合、出力は次のようになります:
Server: MainServer, Port: 8080
API Key Valid: Trueチートシート
個別のアクセサーに private を使用することで、プロパティへのアクセスを制御できます。
読み取り専用プロパティ(private な setter を持つ場合):
public class User
{
public string Username { get; private set; }
public User(string username)
{
Username = username;
}
}外部のコードは Username を読み取ることができますが、変更できるのはクラス自身のみです。
書き込み専用プロパティ(private な getter を持つ場合):
public class Account
{
public string Password { private get; set; }
public bool ValidatePassword(string input)
{
return input == Password;
}
}格納された値を公開せずに入力を受け取りたい機密データに便利です。
完全な読み取り専用プロパティ(getter のみを持つ場合):
public class Circle
{
public double Radius { get; }
public Circle(double radius)
{
Radius = radius;
}
}get; のみを持つプロパティは、コンストラクター内または宣言時にのみ割り当てることができ、オブジェクト作成後は不変(イミュータブル)になります。
自分で試してみよう
using System;
using Settings;
class Program
{
public static void Main(string[] args)
{
// 入力を読み込む
string serverName = Console.ReadLine();
int port = Convert.ToInt32(Console.ReadLine());
string apiKeyToStore = Console.ReadLine();
string apiKeyToValidate = Console.ReadLine();
// TODO: serverName と port を使用して ServerConfig オブジェクトを作成する
// TODO: 書き込み専用プロパティを使用して API キーを設定する
// TODO: API キーを検証し、結果を出力する
// 形式: Server: {ServerName}, Port: {Port}
// API Key Valid: {True/False}
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。