Tengo una clase que quiero usar para almacenar "propiedades" para otra clase. Estas propiedades simplemente tienen un nombre y un valor. Idealmente, lo que me gustaría es poder agregar propiedades escritas , de modo que el "valor" devuelto sea siempre del tipo que quiero que sea.
El tipo siempre debe ser primitivo. Esta clase subclasifica una clase abstracta que básicamente almacena el nombre y el valor como una cadena. La idea es que esta subclase agregará algo de seguridad de tipos a la clase base (además de ahorrarme en alguna conversión).
Entonces, he creado una clase que es (aproximadamente) esto:
public class TypedProperty<DataType> : Property
{
public DataType TypedValue
{
get { // Having problems here! }
set { base.Value = value.ToString();}
}
}
Entonces la pregunta es:
¿Hay una forma "genérica" de convertir de cadena a primitiva?
Parece que no puedo encontrar ninguna interfaz genérica que vincule la conversión en todos los ámbitos (¡algo como ITryParsable hubiera sido ideal!).
fuente
Respuestas:
No estoy seguro de haber entendido sus intenciones correctamente, pero veamos si esto ayuda.
fuente
Convert.ChangeType
no es una solución muy universal y extensible, funciona para la mayoría de los tipos básicos. Si se necesita algo mejor, no hay problema en envolver este método en algo más grande como lo sugirió Tim o usar un método de conversión completamente diferente.El método de lubos hasko falla para los valores nulables. El siguiente método funcionará para nulables. Sin embargo, no se me ocurrió. Lo encontré a través de Google: http://web.archive.org/web/20101214042641/http://dogaoztuzun.com/post/C-Generic-Type-Conversion.aspx Crédito para "Tuna Toksoz"
Uso primero:
La clase está abajo.
fuente
tc
(laTypeConverter
) solo una vez.TypeConverter
es lento porque usa la reflexión para buscar elTypeConverterAttribute
. Si inicializa un únicoTypeConverter
campo privado , debería poder reutilizarloTypeConverter
muchas veces.object
, arroja una excepción. Pude solucionarlo usando `if (typeof (T) .IsPrimitive) {return TConverter.ChangeType <T> (StringValue); } else {objeto o = (objeto) StringValue; volver a; } `como reemplazo para la muestra de usoTConverter.ChangeType<T>(StringValue)
Para muchos tipos (entero, doble, DateTime, etc.), existe un método Parse estático. Puedes invocarlo usando la reflexión:
fuente
TypeDescriptor
es una clase que tiene un métodoGetConvertor
que acepta unType
objeto y luego puede llamar alConvertFrom
método para convertir elvalue
objeto especificado.fuente
Posiblemente podría usar una construcción como una clase de rasgos . De esta manera, tendría una clase auxiliar parametrizada que sabe cómo convertir una cadena a un valor de su propio tipo. Entonces su captador podría verse así:
Ahora, debo señalar que mi experiencia con los tipos parametrizados se limita a C ++ y sus plantillas, pero imagino que hay alguna forma de hacer lo mismo con los genéricos de C #.
fuente
Verifica la estática
Nullable.GetUnderlyingType
. - Si el tipo subyacente es nulo, entonces el parámetro de plantilla no esNullable
, y podemos usar ese tipo directamente - Si el tipo subyacente no es nulo, entonces use el tipo subyacente en la conversión.Parece funcionar para mi:
fuente
Con la inspiración de la respuesta de Bob , estas extensiones también admiten la conversión de valores nulos y todas las conversiones primitivas de vuelta y cuarta.
Ejemplos
fuente
Estoy usando la conversión a través de un objeto. Es un poco más simple.
fuente
Utilicé la respuesta de lobos y funciona. Pero tuve un problema con la conversión de dobles debido a la configuración de la cultura. Entonces agregué
fuente
Otra variación más. Maneja Nulables, así como situaciones donde la cadena es nula y T no es anulable.
fuente
Puede hacerlo en una línea de la siguiente manera:
Codificación feliz;)
fuente