FieldInfo.SetValueメソッドを使って構造体のフィールドに値を設定する方法について。
メソッドに構造体(値型)のインスタンスを渡す場合、メソッドにはインスタンスのコピーが渡される(方法 : メソッドに構造体を渡すこととクラス参照を渡すことの違いを理解する (C# プログラミング ガイド))。
FieldInfo.SetValueも同様で、構造体のインスタンスを渡してもフィールドの値が変更されるのはコピーされたインスタンスの方で、元のインスタンスの方ではない。 そのため、FieldInfo.SetValueに構造体インスタンスを指定しても、見た目上はフィールドの値が変更されないよう見える。
FieldInfo.SetValueメソッドには参照渡し(ref/ByRef)を行うようなオーバーロードは用意されていないので、FieldInfo.SetValueメソッドで構造体フィールドの値を設定するにはなんらかの代替策を取る必要がある。
ボックス化する
Object型に構造体インスタンスを代入することによりボックス化を行い、ボックス化したものをFieldInfo.SetValueメソッドに指定することで参照渡しする。 その後、ボックス化を解除して構造体型に戻す。
VB.NETでは、このような方法でボックス化することはできない。
ValueTypeを使う
Object型に代入してボックス化するかわりに、一旦ValueTypeクラスに変換してFieldInfo.SetValueメソッドに渡す。
FieldInfo.SetValueDirectメソッドを使う
FieldInfo.SetValueメソッドの代わりに、FieldInfo.SetValueDirectメソッドを使う。 FieldInfo.SetValueDirectメソッドでは、値を設定したいインスタンスを指定するかわりに、TypedReferenceを指定する。 C#では、隠しキーワード __makeref を使用することでTypedReferenceを取得することができる。