简体   繁体   English

如何获取数组字段的FieldInfo?

[英]How do I get the FieldInfo of an array field?

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. 这将返回Test2类型,但我不想要数组的类型,我想要FieldInfo或该结构的Fields,以便我可以在其中设置值。

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: 没有 FieldInfo为阵列...你可以通过获取阵列(如重复的值中的项目Array )和迭代...只是使用:

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

Sorry for the initial wrong answer. 抱歉,最初的错误答案。 I was too lazy to create my own Test2 type so I used a string instead. 我懒得创建自己的Test2类型,所以我用了一个字符串代替。 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. 它应该为您提供您正在谈论的FieldInfo。

The problem with @weiqure's technique is that it only works if the array already has at least one element in it. @ weiqure技术的问题在于它只有在数组中至少有一个元素时才有效。 Here is a way to find the array's element type, whether it contains elements or not: 这是一种查找数组元素类型的方法,无论它是否包含元素:

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

And here is how you would use that function: 以下是您将如何使用该功能:

void Test(object targetObject, string fieldName)
{
    FieldInfo field = targetObject.GetType().GetField(fieldName);
    Type elementType;
    bool success = GetArrayElementType(field, out elementType);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM