unidades tabla quinto problemas primaria para medidas longitud kilogramos ejemplos conversiones conversion completa c# reflection

c# - tabla - Tipo de problema de conversión al configurar la propiedad a través de la reflexión



problemas de kilogramos para quinto de primaria (5)

Consolidar y expandir la respuesta de para manejar las enum sugeridas por SilverNinja (y respondidas por thecoop ) y colocar los aprendizajes acumulados en un solo lugar. Esto es un poco más de copia / pastable .;

private void SetApiSettingValue(object source, string propertyName, object valueToSet) { // find out the type Type type = source.GetType(); // get the property information based on the type System.Reflection.PropertyInfo property = type.GetProperty(propertyName); // Convert.ChangeType does not handle conversion to nullable types // if the property type is nullable, we need to get the underlying type of the property Type propertyType = property.PropertyType; var targetType = IsNullableType(propertyType) ? Nullable.GetUnderlyingType(propertyType) : propertyType; // special case for enums if (targetType.IsEnum) { // we could be going from an int -> enum so specifically let // the Enum object take care of this conversion if (valueToSet != null) { valueToSet = Enum.ToObject(targetType, valueToSet); } } else { // returns an System.Object with the specified System.Type and whose value is // equivalent to the specified object. valueToSet = Convert.ChangeType(valueToSet, targetType); } // set the value of the property property.SetValue(source, valueToSet, null); } private bool IsNullableType(Type type) { return type.IsGenericType && type.GetGenericTypeDefinition().Equals(typeof(Nullable<>)); }

Tenemos una propiedad de tipo long? que se llena con un int .

Esto funciona bien cuando acabo de establecer la propiedad directamente obj.Value = v; pero cuando intento establecer la propiedad a través de la reflexión info.SetValue(obj, v, null); me da la siguiente excepción:

El objeto de tipo ''System.Int32'' no se puede convertir al tipo ''System.Nullable`1 [System.Int64]''.

Este es un escenario simplificado:

class TestClass { public long? Value { get; set; } } [TestMethod] public void TestMethod2() { TestClass obj = new TestClass(); Type t = obj.GetType(); PropertyInfo info = t.GetProperty("Value"); int v = 1; // This works obj.Value = v; // This does not work info.SetValue(obj, v, null); }

¿Por qué no funciona al configurar la propiedad a través de la reflection mientras funciona al configurar la propiedad directamente?


Cuando escribes:

obj.Value = v;

el compilador sabe cómo hacer el casting adecuado para usted y compila realmente

obj.Value = new long?((long) v);

Cuando usas la reflexión no hay compilador para ayudarte.


Porque el tipo long tiene un método de conversión implícito.

6.1.2 Conversiones numéricas implícitas

Puede ver el método de conversión implícito como método oculto que existe detrás del símbolo = .

También funciona con tipo nullable:

int i = 0; int? j = i; // Implicit conversion long k = i; // Implicit conversion long? l = i; // Implicit conversion

Pero ir al revés no funciona, porque no existe una conversión implícita para pasar un null a un no nulo:

int? i = 0; int j = i; // Compile assert. An explicit conversion exit... int k = (int)i; // Compile, but if i is null, you will assert at runtime.

¿No tienes que convertir explícitamente un int en un int? ... o un long? .

Sin embargo, cuando utiliza la reflexión, está omitiendo la conversión implícita y asigna directamente el valor a la propiedad. De esta manera, hay que convertirlo explícitamente.

info.SetValue(obj, (long?)v, null);

La reflexión salta todas las cosas dulces escondidas detrás = .


También me encontré con este problema al crear nuevos objetos reflexivamente.

Así es como no hacerlo:

var newOne = Activator.CreateInstance(srcProp.GetType()); srcProp.SetValue(newGameData, newOne, null);

Y así es como se hace:

var newOne = Activator.CreateInstance(srcProp.PropertyType); srcProp.SetValue(newGameData, newOne, null);


Ver el artículo completo: ¿Cómo establecer el valor de una propiedad utilizando Reflection?

código completo si está configurando el valor para el tipo anulable

public static void SetValue(object inputObject, string propertyName, object propertyVal) { //find out the type Type type = inputObject.GetType(); //get the property information based on the type System.Reflection.PropertyInfo propertyInfo = type.GetProperty(propertyName); //find the property type Type propertyType = propertyInfo.PropertyType; //Convert.ChangeType does not handle conversion to nullable types //if the property type is nullable, we need to get the underlying type of the property var targetType = IsNullableType(propertyType) ? Nullable.GetUnderlyingType(propertyType) : propertyType; //Returns an System.Object with the specified System.Type and whose value is //equivalent to the specified object. propertyVal = Convert.ChangeType(propertyVal, targetType); //Set the value of the property propertyInfo.SetValue(inputObject, propertyVal, null); } private static bool IsNullableType(Type type) { return type.IsGenericType && type.GetGenericTypeDefinition().Equals(typeof(Nullable<>)); }

necesita convertir valor como este, es decir, debe convertir valor a su tipo de propiedad como se muestra a continuación

PropertyInfo info = t.GetProperty("Value"); object value = null; try { value = System.Convert.ChangeType(123, Nullable.GetUnderlyingType(info.PropertyType)); } catch (InvalidCastException) { return; } propertyInfo.SetValue(obj, value, null);

necesita hacer esto porque no puede convertir ningún valor arbirario al tipo dado ... así que necesita convertirlo así