tag property c# reflection type-conversion propertyinfo setvalue

c# - property - Establecer una propiedad por reflexión con un valor de cadena



set value property c# (11)

¿Está buscando jugar con Reflection o está buscando construir una pieza de software de producción? Me preguntaría por qué está utilizando la reflexión para establecer una propiedad.

Double new_latitude; Double.TryParse (value, out new_latitude); ship.Latitude = new_latitude;

Me gustaría establecer una propiedad de un objeto a través de Reflexión, con un valor de tipo string . Entonces, por ejemplo, supongamos que tengo una clase de Ship , con una propiedad de Latitude , que es un double .

Esto es lo que me gustaría hacer:

Ship ship = new Ship(); string value = "5.5"; PropertyInfo propertyInfo = ship.GetType().GetProperty("Latitude"); propertyInfo.SetValue(ship, value, null);

Como está, esto lanza una ArgumentException :

El objeto de tipo ''System.String'' no se puede convertir al tipo ''System.Double''.

¿Cómo puedo convertir el valor al tipo adecuado, basado en propertyInfo ?


Como muchos otros han dicho, usted quiere usar Convert.ChangeType :

propertyInfo.SetValue(ship, Convert.ChangeType(value, propertyInfo.PropertyType), null);

De hecho, te recomiendo que mires toda la Clase Convert .

Esta clase y muchas otras clases útiles forman parte del espacio de nombres del System . Encuentro útil escanear ese espacio de nombres cada año para ver qué características me he perdido. ¡Darle una oportunidad!


Me he dado cuenta de que muchas personas están recomendando Convert.ChangeType : esto funciona para algunos casos, sin embargo, tan pronto como comience a utilizar tipos nullable , comenzará a recibir las InvalidCastExceptions :

http://weblogs.asp.net/pjohnson/archive/2006/02/07/Convert.ChangeType-doesn_2700_t-handle-nullables.aspx

Hace unos años se escribió una envoltura para manejar esto, pero eso tampoco es perfecto.

http://weblogs.asp.net/pjohnson/archive/2006/02/07/Convert.ChangeType-doesn_2700_t-handle-nullables.aspx


O podrías intentar:

propertyInfo.SetValue(ship, Convert.ChangeType(value, propertyInfo.PropertyType), null); //But this will cause problems if your string value IsNullOrEmplty...


Probablemente estés buscando el método Convert.ChangeType . Por ejemplo:

Ship ship = new Ship(); string value = "5.5"; PropertyInfo propertyInfo = ship.GetType().GetProperty("Latitude"); propertyInfo.SetValue(ship, Convert.ChangeType(value, propertyInfo.PropertyType), null);


Puede usar Convert.ChangeType() : le permite usar información de tiempo de ejecución en cualquier tipo IConvertible para cambiar los formatos de representación. Sin embargo, no todas las conversiones son posibles, y es posible que deba escribir una lógica de caso especial si desea admitir conversiones de tipos que no son IConvertible .

El código correspondiente (sin manejo de excepciones o lógica de casos especiales) sería:

Ship ship = new Ship(); string value = "5.5"; PropertyInfo propertyInfo = ship.GetType().GetProperty("Latitude"); propertyInfo.SetValue(ship, Convert.ChangeType(value, propertyInfo.PropertyType), null);


Puede utilizar un convertidor de tipo (sin comprobación de errores):

Ship ship = new Ship(); string value = "5.5"; var property = ship.GetType().GetProperty("Latitude"); var convertedValue = property.Converter.ConvertFrom(value); property.SetValue(self, convertedValue);

En términos de organizar el código, podría crear una especie de mezcla que resultaría en un código como este:

Ship ship = new Ship(); ship.SetPropertyAsString("Latitude", "5.5");

Esto se lograría con este código:

public interface MPropertyAsStringSettable { } public static class PropertyAsStringSettable { public static void SetPropertyAsString( this MPropertyAsStringSettable self, string propertyName, string value) { var property = TypeDescriptor.GetProperties(self)[propertyName]; var convertedValue = property.Converter.ConvertFrom(value); property.SetValue(self, convertedValue); } } public class Ship : MPropertyAsStringSettable { public double Latitude { get; set; } // ... }

MPropertyAsStringSettable se puede reutilizar para muchas clases diferentes.

También puede crear sus propios convertidores de tipos personalizados para adjuntarlos a sus propiedades o clases:

public class Ship : MPropertyAsStringSettable { public Latitude Latitude { get; set; } // ... } [TypeConverter(typeof(LatitudeConverter))] public class Latitude { ... }


Responderé a esto con una respuesta general. Por lo general estas respuestas no funcionan con guids. Aquí está una versión de trabajo con guías también.

var stringVal="6e3ba183-89d9-e611-80c2-00155dcfb231"; // guid value as string to set var prop = obj.GetType().GetProperty("FooGuidProperty"); // property to be setted var propType = prop.PropertyType; // var will be type of guid here var valWithRealType = TypeDescriptor.GetConverter(propType).ConvertFrom(stringVal);


Si está escribiendo la aplicación Metro, debe usar otro código:

Ship ship = new Ship(); string value = "5.5"; PropertyInfo propertyInfo = ship.GetType().GetTypeInfo().GetDeclaredProperty("Latitude"); propertyInfo.SetValue(ship, Convert.ChangeType(value, propertyInfo.PropertyType));

Nota:

ship.GetType().GetTypeInfo().GetDeclaredProperty("Latitude");

en lugar de

ship.GetType().GetProperty("Latitude");


Usando Convert.ChangeType y obteniendo el tipo para convertir desde PropertyInfo.PropertyType .

propertyInfo.SetValue( ship, Convert.ChangeType( value, propertyInfo.PropertyType ), null );


Probé la respuesta de LBushkin y funcionó muy bien, pero no funcionará para valores nulos y campos anulables. Así que lo he cambiado a esto:

propertyName= "Latitude"; PropertyInfo propertyInfo = ship.GetType().GetProperty(propertyName); if (propertyInfo != null) { Type t = Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType; object safeValue = (value == null) ? null : Convert.ChangeType(value, t); propertyInfo.SetValue(ship, safeValue, null); }