Setterのないプロパティを変更する(C# WPF)

C#

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があろうがなかろうが、リフレクションで直接アクセスすれば取得も変更も可能です。

関連

C#
スポンサーリンク
Once and Only

コメント