2010-08-19 17 views
11

Trovo che questo comportamento di TryCast in .NET 4.0/VS 2010 sia piuttosto confuso.TryCast non funziona dove DirectCast funziona (.NET 4.0)

A mio avviso TryCast funziona come DirectCast, ma restituirà Niente invece di generare un'eccezione se non è possibile eseguire il cast.

VS 2010/.NET 4

?TryCast(CType(1, Object), String) 
Nothing 
?DirectCast(CType(1, Object), String) 
"1" 

VS 2008/.NET 3,5

?TryCast(CType(1, Object), String) 
Nothing 
?DirectCast(CType(1, Object), String) 
Cannot convert to 'String'. 

.NET 3.5 risultati sono coerenti con ciò in cui credo TryCast fa ... .NET 4 tuttavia non lo è.

Qualcuno può indicarmi la direzione migliore per trasmettere in modo sicuro un oggetto a String in .NET 4?

risposta

16

In base al codice di esempio che inizia con ? Suppongo che stai utilizzando la finestra immediata per eseguire il test corretto? Il problema con questo approccio è che la finestra immediata è un'interpretazione anziché una valutazione reale. Questo lo rende suscettibile ai sottili bug degli angoli e questo è davvero uno di questi.

Se si prende il codice di esempio e lo si aggiunge a una semplice applicazione console VB.Net, si scoprirà che il comportamento del 2010 è identico al comportamento del 2008 (genera un'eccezione).

EDIT

Allora, perché è accaduto questa regressione? Nel 2010 ho completamente riscritto il motore di debug di VB EE (valutatore di espressioni). La vecchia base di codice che ho ereditato era semplicemente troppo costosa da mantenere. Al punto che aggiungere nuove funzionalità al motore era più costoso, riscrivendolo da zero con un'architettura migliore che includeva le nuove funzionalità.

Come detto prima, il debug delle valutazioni è un'interpretazione più che un'esecuzione di codice. Costringe la duplicazione di alcuni algoritmi tra EE e CLR/Compiler. Una delle aree in cui si verifica la duplicazione è nella logica di fusione. Non c'è modo di chiedere al debugger CLR di lanciare un oggetto di debug time, è responsabilità dell'EE determinare se il cast specificato nella lingua sia effettivamente valido.

La vecchia logica di codifica EE aveva numerosi bug (soprattutto nell'area dei generici e degli array). La nuova infrastruttura è conforme alle linee guida CLR. Tuttavia non avrai mai parità al 100% perché non consentirebbe espressioni molto utili in EE (potrei scrivere un post sul blog in futuro). Ma per la maggior parte dei casi il comportamento è valido.

In questo particolare istanza ho aggiunto un bug sottile che consente a DirectCast di un valore digitato su Object per utilizzare gli operatori di conversione runtime di VB rispetto al comportamento specificato che consente solo conversioni CLR. Quindi questa conversione ha successo dove dovrebbe fallire.

+0

Ho appena confermato ciò che mi hai suggerito. DirectCast() effettivamente lancia un'eccezione quando viene eseguita in una valutazione effettiva. Grazie per il chiarimento! – motto

+0

Sarebbe davvero bello se potessi spiegare esattamente cosa è successo. – SLaks

+0

@SLaks, aggiunta una rapida spiegazione. – JaredPar