Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting properties of an object through reflection with different properties types

I am using reflection to populate the properties of an object.

These properties have different types: String, Nullable(double) and Nullable(long) (don't know how to escape the angle brackets here ...). The values for these properties are coming from a dictionary of (string, object) pairs.

So, for example my class has the following properties:

string Description { get; set; } 
Nullable<long> Id { get; set; }
Nullable<double> MaxPower { get; set; }

(in reality there are about a dozen properties) and the dictionary will have entries like <"Description", "A description">, <"Id", 123456>, <"MaxPower", 20000>

Now I am using something like the following to set the values:

foreach (PropertyInfo info in this.GetType().GetProperties())
{
    if (info.CanRead)
    {
         object thisPropertyValue = dictionary[info.Name];

         if (thisPropertyValue != null && info.CanWrite)
         {
             Type propertyType = info.PropertyType;

             if (propertyType == typeof(String))
             {
                 info.SetValue(this, Convert.ToString(thisPropertyValue), null);
             }
             else if (propertyType == typeof(Nullable<double>))
             {
                 info.SetValue(this, Convert.ToDouble(thisPropertyValue), null);
             }
             else if (propertyType == typeof(Nullable<long>))
             {
                 info.SetValue(this, Convert.ToInt64(thisPropertyValue), null);
             }
             else
             {
                 throw new ApplicationException("Unexpected property type");
             }
         }
     }
}

So the question is: do I really have to check the type of each property before assigning the value? Is there anything like a cast that I can perform so that the property value is assigned the type of the corresponding property?

Ideally I would like to be able to do something like the following (which I naively thought might have worked):

         if (thisPropertyValue != null && info.CanWrite)
         {
             Type propertyType = info.PropertyType;

             if (propertyType == typeof(String))
             {
                 info.SetValue(this, (propertyType)thisPropertyValue, null);
             }
        }

Thanks, Stefano

like image 767
Stefano Ricciardi Avatar asked May 14 '09 11:05

Stefano Ricciardi


1 Answers

If the values are already of the correct type, then no: you don't have to do anything. If they might not be right (int vs float, etc), the a simple approach might be:

(edit adjusted for nulls)

Type propertyType = info.PropertyType;
if (thisPropertyValue != null)
{
    Type underlyingType = Nullable.GetUnderlyingType(propertyType);
    thisPropertyValue = Convert.ChangeType(
        thisPropertyValue, underlyingType ?? propertyType);
}
info.SetValue(this, thisPropertyValue, null);
like image 145
Marc Gravell Avatar answered Sep 21 '22 22:09

Marc Gravell