|
|
連載:[完全版]究極のC#プログラミング
Chapter13 自動実装と自動定義
川俣 晶
2010/02/17 |
|
|
13.4 読み出し専用、書き込み専用はない
自動実装プロパティはつねにgetアクセサとsetアクセサの双方が必要とされることに注意が必要である。したがって、以下のケースはどちらもエラーになる。
なぜ、読み出し専用、書き込み専用のプロパティは許可されないのだろうか? その理由は構造を考えれば明らかだろう。
暗黙的に確保されるフィールド(バッキングフィールド)にアクセスする手段がない以上、すべての書き込みと読み出しはプロパティ経由になる。ということは、読み出し専用プロパティはデフォルト値しか読み出せないし、書き込み専用プロパティに書き込んだ内容は永遠に読み出すことができない。つまり、たとえ可能になったとしても存在意義はないのである。
ただし、プロパティ経由ではなく、リフレクション経由でバッキングフィールドにアクセスできることに注意が必要である。
次のリスト13.9は、通常の手段ではアクセスできないバッキングフィールドをリフレクションで検出し、その値を書き換えてしまう例である。もちろん、リフレクションを使えばクラス内部の詳細にいくらでも介入できるわけで、バッキングフィールドも例外ではない。しかし、通常の手段ではソースコード上にいっさい姿を見せることがないバッキングフィールドの書き換えは、ソースコード上での操作と結果の因果関係がわかりにくくなり、保守性を下げる可能性がある。
using System;
using System.Reflection;
class SomeClass
{
public int A { get; private set; }
}
class Program
{
static void Main(string[] args)
{
var a = new SomeClass();
Console.WriteLine("a.A={0}", a.A);
Type t = a.GetType();
foreach (FieldInfo f in t.GetFields(BindingFlags.NonPublic
| BindingFlags.Instance))
{
Console.WriteLine("found: {0}", f.Name);
f.SetValue(a, (object)123);
}
Console.WriteLine("a.A={0}", a.A);
}
}
|
|
リスト13.9 リフレクションによるバッキングフィールドへのアクセス |
a.A=0
found: <A>k__BackingField
a.A=123
|
|
リスト13.9の実行結果 |
Insider.NET 記事ランキング
本日
月間