none
構造体のフィールドをリフレクションで変更したい RRS feed

  • 質問

  • 参照型であれば、FieldInfoのSerValueメソッドを利用すればフィールドを変更できますが、
    値型の場合は、コピーが渡されるので変更できません。

    なにか良い方法はありますか?
    よろしくお願いします。
    2008年10月1日 9:05

回答

  • Object 型変数に入れてやって、それを SetValue に渡せばいいでしょう。
    SetValue した後はもちろん元の変数に書き戻す必要があります。
    2008年10月1日 10:33

すべての返信

  • Object 型変数に入れてやって、それを SetValue に渡せばいいでしょう。
    SetValue した後はもちろん元の変数に書き戻す必要があります。
    2008年10月1日 10:33
  • 構造体をValueType型に入れてSetValueを使えばできますが、そのValueType型を元の構造体の型にキャストできません。

    そこで以下では、Activator.CreateInstanceを使って新しくインスタンスを生成して返しています。

     

    Reflection: Modify value types by reflection
    http://mmarinov.blogspot.com/2007/01/reflection-modify-value-types-by.html

    2008年10月2日 1:53
    モデレータ
  • Hongliangさん、返信ありがとうございます。
     Hongliang さんからの引用
    Object 型変数に入れてやって、それを SetValue に渡せばいいでしょう。
    SetValue した後はもちろん元の変数に書き戻す必要があります。

    なるほど。できました!

    実際に試したサンプルプログラムを載せます。

    class Program
    {
        public struct 構造体
        {
            public int num;     // 値型
            public string str;  // 参照型
        }

        static void Main(string[] args)
        {
            // 構造体のフィールド情報
            FieldInfo numField = typeof(構造体).GetField("num");
            FieldInfo strField = typeof(構造体).GetField("str");

            // 実体生成
            構造体 s = new 構造体();

            // 参照型に代入(ボックス化)
            object o = s;

            // フィールドの変更
            numField.SetValue(o, 3);
            strField.SetValue(o, "文字列");

            // 値型に戻す(ボックス化解除)
            s = (構造体)o;

            // 表示
            Console.WriteLine(s.num);   // => 3
            Console.WriteLine(s.str);   // => 文字列
        }
    }

    2008年10月2日 1:56
  •  trapemiya さんからの引用

    構造体をValueType型に入れてSetValueを使えばできますが、そのValueType型を元の構造体の型にキャストできません。

     

    あれ~、キャストできますね。参照先のブログの内容を鵜呑みにしてしまったようです。すみません。それとも何か別の問題があったのかな?

    でも、

    So because the ValueType class is the base class of all value types, it is normal that you can not cast the variable vt back to the structure MyStructure type.

    とはっきり書かれていますし・・・

    2008年10月2日 4:35
    モデレータ
  • trapemiyaさん、返信ありがとうございます。

     trapemiya さんからの引用

    So because the ValueType class is the base class of all value types, it is normal that you can not cast the variable vt back to the structure MyStructure type.


    の根拠を示す情報がそのブログのどこにもないので、信用できないかもしれませんね。実際にキャストできますし。

    ValueType型が構造体の基底クラスであることと参照型であることより、キャストができると言ってよいのではないでしょうか?
    この辺りに詳しい方がいたら教えてもらえると助かります。
    2008年10月2日 10:08