views:

1371

answers:

3

At the moment my code successfully sets the value of fields/properties/arrays of an object using reflection given a path to the field/property from the root object.

e.g.

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

The above example would set 'MyProperty' property of the 'MyObject' object to 'new value'

I'm unable to use reflection to set a value of a field in a struct which is part of an array of structs because the struct is a value type (within an array).

Here are some test classes/structs...

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; }

Below is how I successfully set the value of normal properties/fields and props/fields in lists...

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);

After that I want the myObject.myStructArray[0].myField = ''my new value" and myObject.myOtherStructArray[1].myOtherField = ''my new value"

All I need is a replacement for the 'FieldInf.SetValue(foundObject, newValue);' line

thanks in advance

+1  A: 

If I had to guess, the bug is in part of the code you omitted, specifically I'd suspect that:

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

is (unintentionally) setting foundObject to a copy of the object at the specified list position.

MarkusQ
Hi thans for answering, please see my feedback below...
Mark
A: 

My question continued...

The only solution i found to a similar problem I had setting a field/property in a struct that is a field was to use...

//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");

Problem is how can I use SetValueDirect on a array/list of structs, i'm guessing my old method above will not work when the structs are in an array because I cannot get the FieldInfo for the struct (because its in an array)?

Mark
A: 

Get the FieldInfo for the array object (not the specific element).

If it's an array, cast it to a System.Array and use Array.SetValue to set the object's value.

Reed Copsey
Thanks for your answer, i don't think that will work because the structure is as follows...MyObject.myStructArray[0].myFieldSo using your method Array.SetValue
Mark
... would to pass in a brand new struct,i'm trying to set the value of a field in a struct thats in an array
Mark
Yes. Whenever you have an array of structs, that's the best approach. You can copy it to a new, local struct, and only overwrite that member, then pass that back in.
Reed Copsey
As a rule of thumb, though, typically structs should be immutable, so typically, you should avoid structs where one member can be changed. The design guidelines explain why in details...
Reed Copsey
OK thanks.Looks like i'm catering for situations that are never going to occur in classes.PS Where are these design guidelines you speak of?
Mark
Part of the design guidelines for .net frameworks is available on MSDN. There is a book written by 2 MS people that explains all the guidelines in detail, though. Is one I highly recommend.
Reed Copsey
Reed Copsey
Cheers, i've got the book via work. Its very thorough and its good to dip into for a quick info fix while working.Any other good .NET books you could recommend?
Mark