سؤال

وأنا أحاول الحصول على معلومات ميدانية من قيمة مجموعة من داخل البنية. حتى الآن ليس لدي ما يلي، ولكن أنا لا أرى كيف للحصول على infomration أريد.

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

وحتى إذا فعلت:

 Type array_type = struct_field.FieldType.GetElementType();

وهذا سيعود نوع TEST2، ولكن أنا لا أريد نوع من مجموعة، أريد FieldInfo أو الحقول من هذا الهيكل حتى أستطيع أن تعيين قيم من داخلها.

هل كانت مفيدة؟

المحلول

وآسف للإجابة خاطئة الأولية. كنت كسول جدا لخلق نوع خاص بي لTEST2 لذلك تستخدم سلسلة بدلا من ذلك. وهنا يكمن الجواب الصحيح (أمل):

ولقد فعلت ما تريد القيام به مع التعليمات البرمجية التالية:

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

وهذا هو خط أهمها:

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

وينبغي أن تعطيك FieldInfo التي كنت تتحدث عنها.

نصائح أخرى

ما هي بالضبط لك بعد؟ هناك <م> هو لا FieldInfo للعناصر في مجموعة ... يمكنك تكرار القيم عن طريق الحصول على مجموعة (كما Array) وبالتكرار ذلك ... مجرد استخدام:

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

والمشكلة مع @ weiqure في الأسلوب هو أنه يعمل فقط إذا كان الصفيف بالفعل عنصر واحد على الأقل في ذلك. هنا هو وسيلة لإيجاد نوع عنصر المصفوفة، سواء كان يحتوي على عناصر أم لا:

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

وهنا هو كيف ستستخدم هذه المهمة:

void Test(object targetObject, string fieldName)
{
    FieldInfo field = targetObject.GetType().GetField(fieldName);
    Type elementType;
    bool success = GetArrayElementType(field, out elementType);
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top