views:

390

answers:

1

Hi,

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

+6  A: 

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);
Marc Gravell
I was going to suggest just trying info.SetValue(this, thisPropertyValue, null); but this seems to be a better solution.
ChrisF
+1 for the Convert.ChangeType method. It's a great solution to avoid the ifs in code.
Darin Dimitrov
@Marc: Thank you, this did the trick ;)@ ChrisF: info.SetValue(this, thisPropertyValue, null) raised an exception when trying to convert from int to double in one of my test cases.
Stefano Ricciardi
@Stefano - it was only a suggestion ;)
ChrisF