简体   繁体   中英

Assigning to an array field through reflection in c#

I use reflection to get FieldInfos in a class and assign to them with FieldInfo.SetValue. It works fine when i assign primitive types (i use Convert.ChangeType to convert from object to type) but doesn't work if the field is an array. It works if i use Array.Cast but the type is only known at runtime so i cant cast. I saw lots of topics on this but none of them worked so far.

I get this exception:

ArgumentException: Object type System.Object[] cannot be converted to target type: System.Single[]

I know why it happens i just can't find a way to convert the data. Any ideas?

EDIT: relevant code:

 public static object Deserialize (string path){
        string[] lines = File.ReadAllLines(path);
        ConstructorInfo ci = type.GetConstructor(Type.EmptyTypes);
        object newObj = ci.Invoke(new object[] {});
        Type type = Type.GetType(lines[0], true);
        FieldInfo[] fields = type.GetFields(BindingFlags.Public);



        for (int i = 1; i < lines.Length; i++){
            FieldInfo thisField = currentType.GetField(lines[i]);
                if (thisField != null) {
                    if (line != "") {
                        if (fieldType == typeof(string)) {
                            thisField.SetValue(currentObject, line);
                            thisField = null;
                        }
                        else if (fieldType.IsPrimitive) {
                            val = Convert.ChangeType(line, fieldType);
                            thisField.SetValue(currentObject, val);
                            thisField = null;
                        }
                        else if (fieldType.IsArray){
                            string[] values = ReadUntil(']');
                            //ReadUntil just returns the values as string[] as read from text file
                            object[] newValues = Convert.ChangeType(values, fieldType);

                            thisField.SetValue(newObj, newValues);
                        }
                    }
                }
            }
        }
        return newObj;
    }

You can use something like this

else if (fieldType.IsArray)
{
    string[] values = ReadUntil(']');
    var elementType = fieldType.GetElementType();
    if (elementType == typeof(string))
        thisField.SetValue(newObj, values);
    else
    {
        var actualValues = Array.CreateInstance(elementType, values.Length);
        for (int i = 0; i < values.Length; i++)
            actualValues.SetValue(Convert.ChangeType(values[i], elementType), i);
        thisField.SetValue(newObj, actualValues);
    }
}

Type.GetElementType method is used to retrieve the type of the array elements, then Array.CreateInstance method to create an array of the desired type, and finally Array.SetValue method to populate the new array elements with the converted values.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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