Pregunta

Actualmente estoy trabajando en una aplicación donde necesito para cargar datos desde una base de datos SQL y luego asignar los valores recuperados en las propiedades de un objeto. Estoy haciendo esto mediante el uso de la reflexión desde los nombres de las propiedades y los nombres de columna son los mismos. Sin embargo, muchas de las propiedades está utilizando un tipo de estructura personalizada que es básicamente un envoltorio de divisas para el tipo decimal. He definido una conversión implícita en mi estructura:

public static implicit operator Currency(decimal d)
{
     return new Currency(d);
}

Esto funciona bien cuando lo uso en el código. Sin embargo, cuando tengo esto:

foreach (PropertyInfo p in props)
{
     p.SetValue(this, table.Rows[0][p.Name], null);
}

Se lanza una excepción ArgumentException que indica que no se puede convertir de System.Decimal de divisas. Estoy confundido, ya que funciona bien en cualquier otra circunstancia.

¿Fue útil?

Solución

pensar que necesitan primera unbox el valor en table.Rows[0][p.Name] como decimal.

En otras palabras:

foreach (PropertyInfo p in props)
{
     if (p.PropertyType == typeof(Currency))
     {
         Currency c = (decimal)table.Rows[0][p.Name];
         p.SetValue(this, c, null);
     }
     else
     {
         p.SetValue(this, table.Rows[0][p.Name], null);
     }
}

Este es un tema que he visto una o dos veces antes, así que en realidad decidí escribir un post sobre ello . Cualquiera que busque un poco más de explicación, no dude en darle una lectura.

Otros consejos

Desafortunadamente, estos operadores de conversión definidas por el usuario no se utilizan por el tiempo de ejecución; que sólo son utilizados por el compilador en tiempo de compilación. Así que si usted toma una decimal inflexible de tipos y la asigna a una Currency inflexible de tipos, el compilador insertará una llamada a su operador de conversión y feliz de todos. Sin embargo, cuando se llama SetValue como que estás haciendo aquí, el tiempo de ejecución que espera para darle un valor del tipo apropiado; el tiempo de ejecución tiene ni idea de la existencia de este operador de conversión, y no vuelvas a llamar a él.

Asumo que table es de tipo DataTable en su código, por lo que el primer paso a paso devuelve un DataRow, y el segundo uno vuelve un object. Entonces PropertyInfo.SetValue también tiene un object como segundo argumento. En ningún lugar en este código de un elenco sucede en el código , por lo que no se aplica el operador de conversión sobrecargado.

En general, sólo se aplica cuando se conocen tipos estáticos (olvidarse de dynamic en C # 4.0 por el momento). No se aplica cuando el boxeo y unboxing cosas. En este caso, el indexador en las cajas DataRow el valor, y trata PropertyInfo.SetValue a unbox a un tipo diferente -. Y no

Mientras que no estoy respondiendo a su problema, creo que en este tipo de situación sería más apropiado utilizar un marco ORM como Entity Framework o NHibernate que mapear sus tablas en sus objetos de dominio y manejar todas las conversiones para usted . El uso de algo así como la reflexión de averiguar qué campos debe rellenar un objeto de dominio es una forma lenta de hacerlo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top