Converting FieldInfo value to a List When List typ

2019-07-23 00:03发布

问题:

I have the following:

    [Serializable()]
    public struct ModuleStruct {
        public string moduleId;
        public bool isActive;
        public bool hasFrenchVersion;
        public string titleEn;
        public string titleFr;
        public string descriptionEn;
        public string descriptionFr;
        public bool isLoaded;
        public List<SectionStruct> sections;
        public List<QuestionStruct> questions;
    }

I create an instance of this and populate it (contents not relevant for question). I have a function which takes the instantiated object as one parameter, lets call it module, and the type of this object as the other parameter: module.GetType().

This function will then, using reflection, and:

    FieldInfo[] fields = StructType.GetFields();
    string fieldName = string.Empty;

The parameter names in the function are Struct and StructType.

I loop through the field names within Struct, pull the values and of the different fields and do something with it. All is well until I get to:

    public List<SectionStruct> sections;
    public List<QuestionStruct> questions;

The function only knows the type of Struct by StructType. In VB, the code is simply:

    Dim fieldValue = Nothing
    fieldValue = fields(8).GetValue(Struct)

and then:

    fieldValue(0)

to get the first element in the list sections; however, in C#, the same code does not work because fieldValue is an object and I cannot do fieldValue[0] on an object.

My question, then, is given that the function only knows the type of Struct by StructType, how do I replicate the VB behaviour in C#, if it is even possible?

回答1:

Here are some (very simple) example code that's pretty much spelled out... I really don't want to do the whole thing for you, because this could be a great lesson in reflection :)

private void DoSomethingWithFields<T>(T obj)
{
    // Go through all fields of the type.
    foreach (var field in typeof(T).GetFields())
    {
        var fieldValue = field.GetValue(obj);

        // You would probably need to do a null check
        // somewhere to avoid a NullReferenceException.

        // Check if this is a list/array
        if (typeof(IList).IsAssignableFrom(field.FieldType))
        {
            // By now, we know that this is assignable from IList, so we can safely cast it.
            foreach (var item in fieldValue as IList)
            {
                // Do you want to know the item type?
                var itemType = item.GetType();

                // Do what you want with the items.
            }
        }
        else
        {
            // This is not a list, do something with value
        }
    }
}