Frage

Ich versuche, das Feld info eines Arrays Wert innerhalb einer Struktur zu erhalten. Bisher habe ich die folgenden, aber ich sehe nicht, wie die infomration zu bekommen was ich will.

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

Also, wenn ich getan habe:

 Type array_type = struct_field.FieldType.GetElementType();

Dies würde Test2 Typ zurückgeben, aber ich nicht den Typ des Arrays, ich will die Fieldinfo oder Felder dieser Struktur, so kann ich Werte von den in ihr festgelegt.

War es hilfreich?

Lösung

Sorry für die anfängliche falsche Antwort. Ich war zu faul, um meinen eigenen Test2 Typen zu erstellen, damit ich stattdessen eine Zeichenfolge verwendet. Hier ist die richtige Antwort (hoffentlich):

Ich habe, was Sie mit dem folgenden Code zu tun:

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

Dies ist die wichtigste Zeile:

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

Es sollten Sie die Fieldinfo, die Sie reden.

Andere Tipps

Was genau sind Sie nach? Es ist keine FieldInfo für die Elemente im Array ... Sie die Werte, indem man das Array iterieren kann (wie Array) und Iterieren es ... nur verwenden:

Array arr = (Array)field.GetValue(obj);

Das Problem mit @ weiqure der Technik ist, dass es funktioniert nur, wenn das Array bereits mindestens ein Element in sich hat. Hier ist ein Weg des Arrays Elementtyp zu finden, ob es Elemente enthält oder nicht:

bool GetArrayElementType(FieldInfo field, out Type elementType)
{
    if (field.FieldType.IsArray && field.FieldType.FullName.EndsWith("[]"))
    {
        string fullName = field.FieldType.FullName.Substring(0, field.FieldType.FullName.Length - 2);
        elementType = Type.GetType(string.Format("{0},{1}", fullName, field.FieldType.Assembly.GetName().Name));
        return true;
    }
    elementType = null;
    return false;
}

Und hier ist, wie Sie diese Funktion verwenden würden:

void Test(object targetObject, string fieldName)
{
    FieldInfo field = targetObject.GetType().GetField(fieldName);
    Type elementType;
    bool success = GetArrayElementType(field, out elementType);
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top