C-3PO、プロパティを変更されそうになる
概要
プロパティについてC-3POと帝国PGのやり取りにより理解を深めます。
ドロイド生産
まずC-3POを生産するためにドロイドクラスを用意します。
そして、ドロイドの型番をプロパティとして表現します。
class Droid { string Model { get; set; } }
早速起動してみましょう。
static void Main(string[] args) { Droid droid = new Droid(); droid.Model = "C-3PO"; Console.WriteLine("ワタシハ、{0}デス。" , droid.Model); Console.ReadKey(); }
エラーです。
ドロイドクラスのプロパティにアクセシビリティを何も設定していないため、デフォルトprivateによりアクセスできません。
publicに変えましょう。これでエラーも消えました。
class Droid { public string Model { get; set; } }
ここで残念ながら帝国のPGによりC-3POのデータが書き換えられてしまいました。
static void Main(string[] args) { Droid droid = new Droid(); droid.Model = "C-3PO"; Console.WriteLine("ワタシハ、{0}デス。" , droid.Model); droid.Model = "B1 battle droid"; Console.WriteLine("ワタシハ、{0}デス。", droid.Model); Console.ReadKey(); }
private防御壁
アクセシビリティをpublicにすることでプロパティが書き換えられてしまったので、setアクセサをprivateにもどします。
class Droid { public string Model { get; private set; } }
これだとまたsetアクセサでドロイドクラスのプロパティにアクセスできずにエラーとなってしまいます。
この場合、コンストラクタであればクラスのメンバなのでprivateなsetアクセサも利用できるので、コンストラクタによる初期化を行います。
class Droid { public Droid(string model) { Model = model; } public string Model { get; private set; } }
これで外部からはプロパティをsetできません。
static void Main(string[] args) { Droid droid = new Droid("C-3PO"); //droid.Model = "C-3PO"; Console.WriteLine("ワタシハ、{0}デス。" , droid.Model); //droid.Model = "B1 battle droid"; Console.WriteLine("ワタシハ、{0}デス。", droid.Model); Console.ReadKey(); }
外部からは...
class Droid { public Droid(string model) { Model = model; } public string Model { get; private set; } public void hack() { Model = "B1 battle droid"; } }
また帝国のPGにデータが書き換えられてしまいました。
static void Main(string[] args) { Droid droid = new Droid("C-3PO"); Console.WriteLine("ワタシハ、{0}デス。" , droid.Model); droid.hack(); Console.WriteLine("ワタシハ、{0}デス。", droid.Model); Console.ReadKey(); }
読み取り専用フィールド展開
思い切ってsetアクセサを取ってしまいます。
そして、明示的なバッキングフィールドをreadonlyで用意し、getアクセサはそれを返すようにします。
class Droid { private readonly string _model; public Droid(string model) { _model = model; } public string Model { get { return _model; } } public void hack() { Model = "B1 battle droid"; } }
この対応によりコンストラクタでのみプロパティが設定できるようになりました。
コンストラクタ以降の処理でプロパティを書き換えようとした場合、読み取り専用のため怒られます。
これで帝国の攻撃は凌げるのではないでしょうか。
参考
- 作者: Ian Griffiths,Matthew Adams,Jesse Liberty,鈴木幸敏,首藤一幸,株式会社情報技研
- 出版社/メーカー: オライリージャパン
- 発売日: 2011/11/29
- メディア: 大型本
- 購入: 2人 クリック: 14回
- この商品を含むブログ (8件) を見る