2011-11-22 12 views
5

(SOLVED) Sto creando un'applicazione che può creare dinamicamente parte del suo controllo, in base ad una descrizione del file XML.
Quello che mi serve ora è qualcosa di molto simile al metodo TryParse(): una possibilità di controllare (senza lanciare/catturare un'eccezione), se un testo nella variabile stringa può essere convertito (o analizzato) in un tipo, quale nome ho in altre variabe (myType).
Il problema è che myType può essere uno qualsiasi dei tipi .NET: DateTime, Bool, Double, Int32 eccVerifica se la stringa può essere convertita in altro tipo diverso

Esempio:

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

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

Come funziona CanCovertTo(string testString, string testType) funzione dovrebbe essere simile?

Il più vicino che ottenga è seguente codice:

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; 
} 

tuttavia, viene generata un'eccezione durante il tentativo di convertire da stringa di sbagliato, e preferisco non usare try {} catch() per questo.


Soluzione:

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

Perché preferisci non usare try/catch per questo? – PVitt

+1

Perché stai provando a convertire un valore in una funzione che si chiama CanConvert? Non puoi semplicemente fare "return converter.CanConvertFrom (typeof (string))" – Grrbrr404

+0

@PVitt: si tratta solo di "best practice", ho letto che dovresti evitare di lavorare con le eccezioni con le normali azioni del programma. Credo che sia il motivo per cui il metodo TryParse() esiste insieme a Parse(). Onestamente, se c'è un metodo migliore di questo, che mi permette di fare ciò di cui ho bisogno, preferisco quello. :) – mj82

risposta

6

Vorrei verificare il metodo TypeConverter.IsValid, anche se:

A partire dalla versione .NET Framework 4, il metodo di cattura IsValid deroghe al CanConvertFrom e Metodi ConvertFrom. Se il tipo di valore di input fa sì che CanConvertFrom restituisca false, o se il valore di input fa sì che ConvertFrom generi un'eccezione, il metodo IsValid restituisce false.

Ciò significa che se non usi il try ... prendi da solo che convertirai il doppio del valore.

+0

Ottima risposta. Questo in realtà risolve un problema in una domanda che ho chiesto la settimana scorsa. – psubsee2003

6

Invece di passare il tipo come stringa, è consigliabile utilizzare generici, ad es.

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

I generici richiedono che l'OP conosca il tipo in fase di compilazione, cosa che sembrerebbe che non lo fosse. – psubsee2003

+0

Quello ** sarebbe perfetto **, se conoscessi il tipo esatto prima, o potrei fare qualcosa del genere: 'bool test1 = CanConvert (testStringOk);' Non lo faccio Conoscere il tipo, tuttavia, è dinamicamente letto e mantenuto nella stringa vaiable. – mj82

+0

@ mj82 - Ah ok, aggiornerò la mia risposta. – James

0

se sono solo tipi predefiniti NET, è possibile eseguire la conversione sulla base di uno System.TypeCode. Puoi memorizzare il codice di digitazione nel tuo XML (o convertire il tuo tipo in un TypeCode) e fare qualcosa del tipo:

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

Ci stavo pensando, ma ci sono troppe righe per quello. :) Con TypeConverter.IsValid, potrebbe essere fatto con 3 linee. Grazie comunque :) – mj82

Problemi correlati