lundi 9 décembre 2019

Parse any primitive type garnered using Reflection from a string

I am retrieving values from text files to build several different types of objects and I'd like one central method of populating the property values for these objects. I would like for the resulting values to benefit from C#'s strong typing which means parsing the values.

The steps being

  • Read the text file's key value pairs of
  • Get a list of all the properties for the type I'm building using reflection.
  • Set the property values to their corresponding key-value pair, converting the string based value to that of the property type.

My current implementation (which works) is:

 public void SetPrimitive(PropertyInfo property, T product, string value)
    {
        if (property.PropertyType == typeof(bool))
        {
            property.SetValue(product, bool.Parse(value));
        }
        else if (property.PropertyType == typeof(int))
        {
            property.SetValue(product, int.Parse(value));
        }
        else if (property.PropertyType == typeof(double))
        {
            property.SetValue(product, double.Parse(value));
        }
        else if (property.PropertyType == typeof(char))
        {
            property.SetValue(product, char.Parse(value));
        }
        else if (property.PropertyType == typeof(float))
        {
            property.SetValue(product, float.Parse(value));
        }
        else if (property.PropertyType == typeof(long))
        {
            property.SetValue(product, long.Parse(value));
        }
        else if (property.PropertyType == typeof(short))
        {
            property.SetValue(product, short.Parse(value));
        }
        else if (property.PropertyType == typeof(string))
        {
            property.SetValue(product, value);
        }
        else
        {
            throw new Exception($"Invalid type '{property.PropertyType}'. This class will need to be extended to support this.");
        }

As you can see this isn't very extensible, and fairly wordy.

I've tried working with Convert or TypeConverters, as is seen in several similar questions, to parse the appropriate values and just plain typecasting but, unlike with the developers asking those questions, I am retrieving the type to convert to via reflection using 'TypeOf(T).GetProperties' and it seems unwilling to convert the value, the compiler complaining that it isn't a recognized type. This, despite it being able to confirm or deny an objects type in the various if statements above.

My theory on it is this: It doesn't know at compile time since the method is building various different types that it doesn't know about till runtime. Hence me trying to code around property.PropertyType is causing compiler confusion. However it is easily able to match any type against another and confirm/deny whether it matches.

Is there a specific way I can write this to get TypeConverter or Convert to work as expected? I'd like this to work for all primitives out of the box and let other devs add on to it if they wanted to be able to set more complex types going forward.

TLDR; I have a working approach but its messy and it feels like there should be a better way to do this.





Aucun commentaire:

Enregistrer un commentaire