コードはこんな感じ。
//呼び出し元
HogeEx he = new HogeEx();
Type tp = typeof(Hoge);
FieldInfo info = tp.GetField("_bar", BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Instance);
info.SetValue(he, true);
internal class Hoge
{
// Fields
public bool _foo = true;
private bool _bar = false;
}
internal class HogeEx : Hoge
{
// Fields
public bool _fooEx = true;
private bool _barEx = false;
}
HogeEx he = new HogeEx();
Type tp = typeof(Hoge);
FieldInfo info = tp.GetField("_bar", BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Instance);
info.SetValue(he, true);
internal class Hoge
{
// Fields
public bool _foo = true;
private bool _bar = false;
}
internal class HogeEx : Hoge
{
// Fields
public bool _fooEx = true;
private bool _barEx = false;
}
ポイントとしては、
- 実際にprivateフィールドを持っているクラスのタイプを指定する
- Type.GetField()の第二引数に、BindingFlags.Instance|BindingFlags.NonPublicを指定する
- 値を突っ込む場合、↑に加え、BindingFlags.SetFieldを指定する
です。
たとえば、HttpRequestのFormに対して強引に値を突っ込みたい場合を考えてみます。HttpRequestのプロパティForm(NameValueCollectionの派生クラス)は参照のみの仕様です。値をセットしようとすると例外が発生します。これは、Form(NameValueCollection)のベースクラスであるNameObjectCollectionBaseのReadOnlyプロパティにより制御しています。そのプロパティの元はprivate変数の_readOnlyとなります。これにfalseを設定すればよい。ということになります。
HttpRequest req = new HttpRequest("", "http://localhost/", ""); //適当なURLが指定できないのでlocalhostを指定
Type tp = typeof(NameObjectCollectionBase);
FieldInfo info = tp.GetField("_readOnly", BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Instance);
info.SetValue(req.Form, false);
req.Form.Add("foo", "bar");
Type tp = typeof(NameObjectCollectionBase);
FieldInfo info = tp.GetField("_readOnly", BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Instance);
info.SetValue(req.Form, false);
req.Form.Add("foo", "bar");
0 件のコメント:
コメントを投稿