web-dev-qa-db-ja.com

リフレクションを使用して構造体インスタンスにプロパティを設定する方法はありますか?

構造体にプロパティを設定するコードを書き込もうとしていますが(構造体のプロパティであることが重要です)、失敗します。

System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle();
PropertyInfo propertyInfo = typeof(System.Drawing.Rectangle).GetProperty("Height");
propertyInfo.SetValue(rectangle, 5, null);

高さの値(デバッガーによって報告される)は、何にも設定されません。デフォルト値の0のままです。

私は以前にクラスについてたくさんの反省をしました、そしてこれはうまくいきました。また、構造体を扱う場合、フィールドを設定する場合はFieldInfo.SetValueDirectを使用する必要があることは知っていますが、PropertyInfoに相当するものはわかりません。

48
Victor Chelaru

rectangleの値はボックス化されていますが、変更されているボックス化された値が失われています。これを試して:

Rectangle rectangle = new Rectangle();
PropertyInfo propertyInfo = typeof(Rectangle).GetProperty("Height");
object boxed = rectangle;
propertyInfo.SetValue(boxed, 5, null);
rectangle = (Rectangle) boxed;
68
Jon Skeet

SetValueDirect について聞いたことがありますか?彼らがそれを成し遂げた理由があります。 :)

struct MyStruct { public int Field; }

static class Program
{
    static void Main()
    {
        var s = new MyStruct();
        s.GetType().GetField("Field").SetValueDirect(__makeref(s), 5);
        System.Console.WriteLine(s.Field); //Prints 5
    }
}

文書化されていない__makeref以外にも使用できる方法がありますが(System.TypedReferenceを参照)、より面倒です。

14
Mehrdad