15

を含むリフレクション(最終的にはコンパイル時に不明)を使用しようとしてobjectいますstruct。限りはTypedReference.MakeTypedReferenceありますが、壁にぶつかりました。

これが私のクラスと構造体です

public class MyObject
{
    public int Id;
    public Money Amount; 
}

public struct Money
{
    public int Vaule;
    public string Code;
}

そして、これが私がリフレクションを使ってMyObjectの「Amount」の「Code」を設定しようとしている方法です。上で述べたように、私はコンパイル時にこれらのタイプについて知らない解決策を探しています(それは簡単すぎるでしょう!)

これが私がこれまでに持っているコードです(コードを単純にするために[0]、[1]を使用しました)

var obj = new MyObject() { Id = 1 };
obj.Amount.Vaule = 10;
obj.Amount.Code = "ABC";

FieldInfo[] objFields = obj.GetType().GetFields();
FieldInfo[] moneyFields = objFields[1].GetValue(obj).GetType().GetFields();

List<FieldInfo> fields = new List<FieldInfo>() { objFields[1] };
fields.AddRange( moneyFields );

TypedReference typeRef = TypedReference.MakeTypedReference( 
                           objFields[1].GetValue( obj ), fields.ToArray() );

moneyFields[1].SetValueDirect( typeRef, "XXX" );

TypedReference.MakeTypedReferenceは次のように爆発します。FieldInfoがターゲットタイプと一致しません。」同様に、私が合格した場合objFields[1]。そして、パスするだけmoneyFieldsで、「TypedReferencesをプリミティブとして再定義することはできません」というメッセージが表示されます。

なんで?ランダムテストフィクスチャを作成していて、クラスフィールドにランダムデータを入力したいとします:)

4

1 に答える 1

19

率直に言って、ここでは何も必要ありませんTypedReference-ボックス化された構造体だけが正常に機能するはずです:

    var amountField = obj.GetType().GetField("Amount");
    object money = amountField.GetValue(obj);
    var codeField = money.GetType().GetField("Code");
    codeField.SetValue(money, "XXX");
    amountField.SetValue(obj, money);

でも!私はあなたにいくつかのことをアドバイスします:

  • プロパティの代わりにパブリックフィールドは通常、良い考えではありません。それはしばしば後であなたを噛むでしょう
  • 可変構造体(つまり、作成後に変更できる構造体)は、ほとんどの場合良い考えではなく、さらに頻繁に噛み付き、激しく噛みます。
  • 可変構造体とパブリックフィールドを組み合わせると複雑になりますが、後で変更するのは非常に問題があります
于 2012-11-09T12:40:34.303 に答える