Tech Off Thread

9 posts

Forum Read Only

This forum has been made read only by the site admins. No new threads or comments can be added.

Reflection, dynamically set property values

Back to Forum: Tech Off
  • User profile image
    devnull

    i am getting cannot Invalid cast from System.String to System.Web.UI.WebControls.Unit using this code:

    // pi = PropertyInfo[] for an ImageButton
    // value is a string (25)
    // pi[i] at the moment is Width
    Type propertyType = pi[i].PropertyType;
    object convertedValue = Convert.ChangeType(value, propertyType); <-- error here

    i can use System.Web.UI.WebControls.Unit.Parse() but it is not a good solution because i am trying to set the property values dynamically, doing switch statement for each type is a mess.

    there must be a way to do this, any ideas?

    thanks

  • User profile image
    lorad

    If this is a repost I am sorry.

    Lock at ChangeType it only supports Boolean, Char, SByte, Byte, Int{X}, Uint{X}, Single, Double, Decimal, DateTime and String.

    The System.Web.UI.WebControls.Unit is not a supported type. So you will have to special case that type. If you catch InvalidCastException you can do the right thing at that point.

    Unless the types have the same base type.  

  • User profile image
    jmbledsoe

    You know the property Type that you want to convert the value to.  One idea is to (through reflection) see if the target Type has a Parse method, and if it does, dynamically invoke it to parse the value.  If not, you can use the Convert method that you're currently using.

    That will simplify your code quite a bit, since there are a whole lot of types that implement Parse.

  • User profile image
    Sven Groot

    The proper way to do this is to check whether the type you're converting to has a TypeConverter. A lot of non-basic types, including Unit, implement this because TypeConverter is also the way the designer in Visual Studio is able to use these types. If it doesn't have a TypeConverter, try falling back to Convert, and if that fails you most likely can't convert.
    An example:

    object convertedValue = null;
    object[] attributes = propertyType.GetCustomAttributes(typeof(System.ComponentModel.TypeConverterAttribute), false);
    foreach( System.ComponentModel.TypeConverterAttribute converterAttribute in attributes )
    {
       System.ComponentModel.TypeConverter converter = (System.ComponentModel.TypeConverter)Activator.CreateInstance(Type.GetType(converterAttribute.ConverterTypeName));
       if( converter.CanConvertFrom(value.GetType()) )
       {
          convertedValue = converter.ConvertFrom(value);
          break;
       }
    }
    if( convertedValue == null )
    {
       try
       {
          convertedValue = Convert.ChangeType(value, propertyType);
       }
       catch( InvalidCastException )
       {
          Console.WriteLine("Can't convert");
       }
    }

  • User profile image
    phreaks

    Sven Groot wrote:
    

    The proper way to do this is to check whether the type you're converting to has a TypeConverter. A lot of non-basic types, including Unit, implement this because TypeConverter is also the way the designer in Visual Studio is able to use these types. If it doesn't have a TypeConverter, try falling back to Convert, and if that fails you most likely can't convert.
    An example:

    object convertedValue = null;
    object[] attributes = propertyType.GetCustomAttributes(typeof(System.ComponentModel.TypeConverterAttribute), false);
    foreach( System.ComponentModel.TypeConverterAttribute converterAttribute in attributes )
    {
       System.ComponentModel.TypeConverter converter = (System.ComponentModel.TypeConverter)Activator.CreateInstance(Type.GetType(converterAttribute.ConverterTypeName));
       if( converter.CanConvertFrom(value.GetType()) )
       {
          convertedValue = converter.ConvertFrom(value);
          break;
       }
    }
    if( convertedValue == null )
    {
       try
       {
          convertedValue = Convert.ChangeType(value, propertyType);
       }
       catch( InvalidCastException )
       {
          Console.WriteLine("Can't convert");
       }
    }



    That's a pretty useful chunk of code.

    /Sven Groot Saves the Day?

  • User profile image
    Sven Groot

    As an addition, if value isn't always a string, you might want to check for TypeConvertors on the source type as well, then see if those can convert to the required type using CanConvertTo.

  • User profile image
    ilya

    Sven Groot wrote:
    

    The proper way to do this is to check whether the type you're converting to has a TypeConverter. A lot of non-basic types, including Unit, implement this because TypeConverter is also the way the designer in Visual Studio is able to use these types. If it doesn't have a TypeConverter, try falling back to Convert, and if that fails you most likely can't convert.
    An example:

    object convertedValue = null;
    object[] attributes = propertyType.GetCustomAttributes(typeof(System.ComponentModel.TypeConverterAttribute), false);
    foreach( System.ComponentModel.TypeConverterAttribute converterAttribute in attributes )
    {
       System.ComponentModel.TypeConverter converter = (System.ComponentModel.TypeConverter)Activator.CreateInstance(Type.GetType(converterAttribute.ConverterTypeName));
       if( converter.CanConvertFrom(value.GetType()) )
       {
          convertedValue = converter.ConvertFrom(value);
          break;
       }
    }
    if( convertedValue == null )
    {
       try
       {
          convertedValue = Convert.ChangeType(value, propertyType);
       }
       catch( InvalidCastException )
       {
          Console.WriteLine("Can't convert");
       }
    }



    Just to simplify some of the code.

    object convertedValue = null;
    System.ComponentModel.TypeConverter converter = System.ComponentModel.TypeDescriptor.GetConverter(propertyType);
    if(converter != null && converter.CanConvertFrom(value.GetType()))
    {
         convertedValue = converter.ConvertFrom(value);
    }
    else
    {
        convertedValue = Convert.ChangeType(value, propertyType);
    }

    Let me know if this helps.

    Thanks,
    Ilya
  • User profile image
    devnull

    sweet, works like a charm. thanks

  • User profile image
    Sven Groot

    ilya wrote:
    System.ComponentModel.TypeConverter converter = System.ComponentModel.TypeDescriptor.GetConverter(propertyType);

    Cool, I didn't know about that method. See, even I learn stuff in here. Tongue Out

Conversation locked

This conversation has been locked by the site admins. No new comments can be made.