2011-11-22 6 views
5

(SOLUCIONADO) Estoy construyendo una aplicación que puede crear parte de su control de forma dinámica, basándose en alguna descripción del archivo XML.
Lo que necesito ahora es algo muy similar al método TryParse(): una posibilidad de verificar (sin lanzar/atrapar excepciones), si un texto en una variable de cadena se puede convertir (o analizar) a un tipo, el nombre que tengo otra variabe (myType).
problema es que myType puede ser cualquiera de los tipos de .NET: DateTime, Bool, Double, Int32 etc.Prueba si la cadena se puede convertir a otra, varios tipos

Ejemplo:

string testStringOk = "123"; 
string testStringWrong = "hello"; 
string myType = "System.Int32"; 

bool test1 = CanCovertTo(testStringOk, myType);  //true 
bool test2 = CanCovertTo(testStringWrong, myType); //false 

¿Cómo CanCovertTo(string testString, string testType) función debe ser similar?

Lo más cerca que consigo es siguiente código:

private bool CanCovertTo(string testString, string testType) 
{ 
    Type type = Type.GetType(testType, null, null); 
    TypeConverter converter = TypeDescriptor.GetConverter(type); 

    converter.ConvertFrom(testString); //throws exception when wrong type 
    return true; 
} 

sin embargo, se produce una excepción al intentar convertir de cadena mal, y yo prefiero no utilizar try {} catch() para eso.


Solución:

private bool CanCovertTo(string testString, string testType) 
{ 
    Type type = Type.GetType(testType, null, null); 
    TypeConverter converter = TypeDescriptor.GetConverter(type); 
    return converter.IsValid(testString); 
} 
+1

¿Por qué prefieres no usar try/catch para eso? – PVitt

+1

¿Por qué intenta convertir un valor en una función que se llama CanConvert? ¿No puede simplemente hacer "devolver convertidor.CanConvertFrom (typeof (cadena))" – Grrbrr404

+0

@PVitt: se trata simplemente de "mejores prácticas", he leído que debe evitar trabajar con excepciones con acciones normales del programa. Creo que es por eso que el método TryParse() existe junto con Parse(). Honestamente, si hay un método mejor que este, que me permite hacer lo que necesito, prefiero ese. :) – mj82

Respuesta

6

Me gustaría comprobar el método TypeConverter.IsValid, aunque:

partir de la versión de .NET Framework 4, el método IsValid atrapa excepciones a la CanConvertFrom y ConvertFrom métodos. Si el tipo de valor de entrada hace que CanConvertFrom devuelva false, o si el valor de entrada hace que ConvertFrom genere una excepción, el método IsValid devuelve falso.

Eso significa que si no utiliza el intento ... atrapar por sí mismo, va a convertir el doble del valor.

+0

Gran respuesta. Esto realmente resuelve un problema en una pregunta que hice la semana pasada. – psubsee2003

6

En lugar de pasar el tipo como una cadena, debe hacer uso de genéricos, p. Ej.

public bool CanConvert<T>(string data) 
{ 
    TypeConverter converter = TypeDescriptor.GetConverter(typeof(T)); 
    return converter.IsValid(data); 
} 

Uso

bool test1 = CanConvert<Int32>("1234"); // true 
bool test2 = CanConvert<Int32>("hello"); // false 
+0

Los genéricos requieren que el OP conozca el tipo en el tipo de compilación, que parece que no. – psubsee2003

+0

Eso ** sería perfecto **, si supiera el tipo exacto antes, o podría hacer algo como esto: 'bool test1 = CanConvert (testStringOk);' I not not sin embargo, conozca el tipo, se lee dinámicamente y se mantiene en una cadena variable. – mj82

+0

@ mj82 - Ah, de acuerdo, actualizaré mi respuesta para que se ajuste. – James

0

Si no son más que los tipos predefinidos NET, puede hacer la conversión basado en una System.TypeCode. Puede almacenar el typecode en su XML (o convertir su tipo de cadena a un TypeCode) y hacer algo como:

switch (code) 
{ 
    case TypeCode.Boolean: 
     bool.TryParse(value, out result); 
     break; 
    case TypeCode.Int32: 
     int.TryParse(value, out result); 
    ... 
} 
+0

He estado pensando en eso, pero hay demasiadas líneas para eso. :) Con TypeConverter.IsValid, podría hacerse con 3 líneas. Gracias de cualquier manera :) – mj82

Cuestiones relacionadas