private fieldならPrivateObjectを使ってGetFieldできますし、
private getter / setterであってもGetProperty / SetPropertyが使えます。
var testClass = new TestClass();
var obj = new PrivateObject(testClass);
int testPorperty = obj.GetProperty("TestProperty");
obj.SetProperty("TestProperty", testProperty);
では以下のようにそもそもSetterすら無かったらどうなるのでしょうか?
public int Hoge { get; } = 4;
実はPrivateObjectではSetPropertyを呼び出せません。
そりゃそうですよね。そんなSetter無いんですからリフレクションで呼んだところで、無いものは無いです。
普段のコーディングには何の問題もないのですが、UnitTestを書くときにsetterのないプロパティの値を書き換えたい時があります。
そういう時は強引に押し通るしかありません。
var testClass = new TestClass();
var field = typeof(TestClass).GetField("<TestProperty>k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic);
var testPorperty = field.GetValue(testClass);
field.SetValue(testClass , testPorperty);
<プロパティ名>k__BackingFieldというのはプロパティに自動実装されるprivate fieldです。通常はアクセスできませんが、リフレクションなら名前さえ知っていれば取得できます。
話の要点は、プロパティのgetter/setterは自動実装で実際にはprivate fieldを<プロパティ名>k__BackingFieldという名前で確保している。
getter/setterがあろうがなかろうが、リフレクションで直接アクセスすれば取得も変更も可能です。
コメント