2009-03-20 7 views
3

現時点では、コードはフィールド/プロパティ/配列へのパスを指定してオブジェクトのフィールド/プロパティをルートオブジェクトから取得します。リフレクションを使用して構造体の配列の一部である構造体のフィールドの値を設定する

//MyObject.MySubProperty.MyProperty 
SetValue('MySubProperty/MyProperty', 'new value', MyObject); 

上記の例では、「新しい価値」私はある構造体のフィールドの値を設定するためにリフレクションを使用することができませんよ

に「MyObjectを」オブジェクトの「MYPROPERTY」プロパティを設定します構造体は値の型(配列内)なので、構造体の配列の一部。ここで

public void SetValue(string pathToData, object newValue, object rootObject) 
{ 
    object foundObject = rootObject; 
    foreach (string element in pathToData.Split("/")) 
    { 
     foundObject = //If element is [Blah] then get the 
         //object at the specified list position 
     //OR 
     foundObject = //Else get the field/property 
    } 

    //Once found, set the value (this is the bit that doesn't work for 
    //       fields/properties in structs in arrays) 
    FieldInf.SetValue(foundObject, newValue); 
} 

object myObject = new MyClass(); 
SetValue("/myStructArray/[0]/myField", "my new value", myObject); 
SetValue("/myOtherStructArray/[1]/myOtherField", "my new value", myObject); 

...

以下
public class MyClass { 
     public MyStruct[] myStructArray = new MyStruct[] { 
      new MyStruct() { myField = "change my value" } 
     }; 
     public MyStruct[] myOtherStructArray = new MyStruct[] { 
      new MyStruct() { myOtherField = "change my value" }, 
      new MyStruct() { myOtherField = "change my other value" } 
     }; 
} 

public struct MyStruct { public string myField; public string myOtherField; } 

は私が成功し、通常のプロパティ/フィールドとリストの小道具/フィールドの値を設定する方法です...いくつかのテストクラス/構造体ですその後、私はmyObject.myStructArray [0] .myField = ''私の新しい値 'を返します。 myObject.myOtherStructArray [1] .myOtherField =' '私の新しい値」

私はすべてdは 'FieldInf.SetValue(foundObject、newValue);の代わりです。ライン

事前

答えて

3

(特定の要素ではなく)配列オブジェクトのFieldInfoを取得します。

配列の場合は、配列をSystem.Arrayにキャストし、Array.SetValueを使用してオブジェクトの値を設定します。原因ボクシング/アンボクシングへ

+0

おかげで、私のフィードバックを参照してください。あなたの答えは、構造が以下の通りであるためにうまくいくとは思わない... MyObject.myStructArray [0] .myField したがって、Array.SetValueメソッドを使用して – Mark

+0

... 配列の構造体にフィールドの値を設定しようとしています – Mark

+1

はい。あなたが構造体の配列を持っているときはいつでも、それが最善の方法です。それを新しいローカル構造体にコピーし、そのメンバを上書きするだけでそれを渡すことができます。 –

1

でのおかげで、私は推測していた場合は、バグがあなたが省略コードの一部であり、特に私はと思われるだろう:

foundObject = //If element is [Blah] then get the 
        //object at the specified list position 

があるが(意図せず)にfoundObjectを設定します特定のリスト位置にあるオブジェクトのコピー

+0

こんにちはthansに答えるために、...以下のため – Mark

0

私の質問続け...

私は、フィールドを使用していたある構造体のフィールド/プロパティを設定していた同様の問題に見つけた唯一の解決策...

//GrandParentObject is myObject 
//GrandParentType is typeof(MyClass) 
//FieldIWantedToSet is the field info of myStruct.FieldIWantedToSet 
FieldInfo oFieldValueTypeInfo = GrandParentType.GetField("myStruct"); 
TypedReference typedRefToValueType = TypedReference.MakeTypedReference(GrandParentObject, new FieldInfo[] { oFieldValueTypeInfo }); 
FieldIWantedToSet.SetValueDirect(typedRefToValueType, "my new value"); 

問題はどうやって構造体の配列/リストにSetValueDirectを使用することができますか?構造体のFieldInfoを取得できないため、構造体が配列内にあるときに上記の古いメソッドが動作しないと思います。

2

、次の構造体のメンバの任意の種類のために、あなたが探している正確に何をすべき:

var property = this.GetType().GetProperty(myPropertyName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public); 
ValueType vthis = this; 
property.SetValue(vthis, myValue, null); // myValue is the value/object to be assigned to the property. 
this = (UnderlyingsList)vthis;