Search code examples
c#reflectioncastinggetproperty

Convert to a Type on the fly in C#.NET


Alternative Title: Dynamically convert to a type at runtime.

I want to to convert an Object to a type that will be assigned at runtime.

For example, assume that I have a function that assigns a string value(from a TextBox or Dropdownlist) to an Object.Property.

How would I convert the value to proper type? For instance, it could be an integer, string, or enum.

Public void Foo(object obj,string propertyName,object value)
{
  //Getting type of the property og object.
  Type t= obj.GetType().GetProperty(propName).PropertyType;

  //Now Setting the property to the value .
  //But it raise an error,because sometimes type is int and value is "2"
  //or type is enum (e.a: Gender.Male) and value is "Male"
  //Suppose that always the cast is valid("2" can be converted to int 2)

  obj.GetType().GetProperty(propName).SetValue(obj, value, null);
}

Solution

  • You need to use the Convert.ChangeType(...) function [note: in the function below, the input propertyValue could just as easily have been of type object ... I just had a string version pre-baked]:

    /// <summary>
    /// Sets a value in an object, used to hide all the logic that goes into
    ///     handling this sort of thing, so that is works elegantly in a single line.
    /// </summary>
    /// <param name="target"></param>
    /// <param name="propertyName"></param>
    /// <param name="propertyValue"></param>
    public static void SetPropertyValueFromString(this object target,               
                                  string propertyName, string propertyValue)
    {
        PropertyInfo oProp = target.GetType().GetProperty(propertyName);
        Type tProp = oProp.PropertyType;
    
        //Nullable properties have to be treated differently, since we 
        //  use their underlying property to set the value in the object
        if (tProp.IsGenericType
            && tProp.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
        {
            //if it's null, just set the value from the reserved word null, and return
            if (propertyValue == null)
            {
                oProp.SetValue(target, null, null);
                return;
            }
    
            //Get the underlying type property instead of the nullable generic
            tProp = new NullableConverter(oProp.PropertyType).UnderlyingType;
        }
    
        //use the converter to get the correct value
        oProp.SetValue(target, Convert.ChangeType(propertyValue, tProp), null);
    }