views:

588

answers:

2

I'm trying to get the field info of an array value from within a struct. So far I have the following, but I dont see how to get the infomration I want.

    [StructLayout(LayoutKind.Sequential)]
    public struct Test
    {
        public byte Byte1;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst=3)]
        public Test2[] Test1;
    }

    BindingFlags struct_field_flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly;
    FieldInfo[] all_struct_fields = typeof(Test).GetFields(struct_field_flags);
    foreach (FieldInfo struct_field in all_struct_fields)
    {
        if(struct_field.FieldType.IsArray)
        {
           // Get FieldInfo for each value in the Test1 array within Test structure
        }
    }

So if I did:

 Type array_type = struct_field.FieldType.GetElementType();

This would return Test2 type, but I dont want the type of the array, I want the FieldInfo or Fields of that structure so I can set values from within it.

+3  A: 

What exactly are you after? There is no FieldInfo for the items in the array... you can iterate the values by getting the array (as Array) and iterating it... just use:

Array arr = (Array)field.GetValue(obj);
Marc Gravell
I would like to get the FieldInfo of Test2 so that I could set values from within that structure
SwDevMan81
For Test1 yes, but I want it for the array of Test2's. If it is an array, I want to get the FieldInfo of the array type so that I can do field.SetValue(obj, value) for the Test1 value.
SwDevMan81
You've lost me somewhere between Test1 and Test2... if you mean each instance inside the array, then treat each instance as an object... then you have GetType() etc. Or use arr.GetType().GetElementType(). But there is no field that points *inside* the array.
Marc Gravell
+1  A: 

Sorry for the initial wrong answer. I was too lazy to create my own Test2 type so I used a string instead. Here's the right answer (hopefully):

I did what you want to do with the following code:

class Program
{
    static void Main(string[] args)
    {
        object sampleObject = GetSampleObject();
        FieldInfo[] testStructFields = typeof(Test).GetFields();

        foreach (FieldInfo testStructField in testStructFields)
        {
            if (testStructField.FieldType.IsArray)
            {
                // We can cast to ILIst because arrays implement it and we verfied that it is an array in the if statement
                System.Collections.IList sampleObject_test1 = (System.Collections.IList)testStructField.GetValue(sampleObject);
                // We can now get the first element of the array of Test2s:
                object sampleObject_test1_Element0 = sampleObject_test1[0];

                // I hope this the FieldInfo that you want to get:
                FieldInfo myValueFieldInfo = sampleObject_test1_Element0.GetType().GetField("MyValue");

                // Now it is possible to read and write values
                object sampleObject_test1_Element0_MyValue = myValueFieldInfo.GetValue(sampleObject_test1_Element0);
                Console.WriteLine(sampleObject_test1_Element0_MyValue); // prints 99
                myValueFieldInfo.SetValue(sampleObject_test1_Element0, 55);
                sampleObject_test1_Element0_MyValue = myValueFieldInfo.GetValue(sampleObject_test1_Element0);
                Console.WriteLine(sampleObject_test1_Element0_MyValue); // prints 55
            }
        }
    }

    static object GetSampleObject()
    {
        Test sampleTest = new Test();
        sampleTest.Test1 = new Test2[5];
        sampleTest.Test1[0] = new Test2() { MyValue = 99 };
        object sampleObject = sampleTest;
        return sampleObject;
    }
}

[StructLayout(LayoutKind.Sequential)]
public struct Test2
{
    public int MyValue;
}

[StructLayout(LayoutKind.Sequential)]
public struct Test
{
    public byte Byte1;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
    public Test2[] Test1;
}

This is the most important line:

FieldInfo myValueFieldInfo = sampleObject_test1_Element0.GetType().GetField("MyValue");

It should give you the FieldInfo that you are talking about.