2012-03-26 9 views
10

Supponiamo di avere un IEnumerable<int> e voglio che questi vengano convertiti nei loro caratteri equivalenti ASCII.IEnumerable.Cast() vs casting in IEnumerable.Select()

Per un singolo intero, sarebbe solo (char)i, quindi c'è sempre collection.Select(i => (char)i), ma ho pensato che sarebbe stato un tad cleaner per utilizzare collection.Cast().

Qualcuno può spiegare perché ottengo un InvalidCastException quando uso collection.Cast<char>() ma non con collection.Select(i => (char)i)?

Modifica: Interessante, quando chiamo collection.OfType<char>() ottengo un set vuoto.

risposta

10

I metodi Cast<T> e OfType<T> eseguono solo conversioni di riferimento e unboxing. Quindi non possono convertire un tipo di valore in un altro tipo di valore.

I metodi operano sull'interfaccia non generica IEnumerable, quindi in pratica convertono da IEnumerable<object> a IEnumerable<T>. Pertanto, la ragione per cui non è possibile utilizzare Cast<T> per convertire da IEnumerable<int> a IEnumerable<char> è la stessa ragione per cui non è possibile trasmettere un valore boxing int a char.

In sostanza, Cast<char> nel tuo esempio non riesce perché il seguente esito negativo:

object ascii = 65; 
char ch = (char)ascii; <- InvalidCastException 

See Jon Skeet di eccellente EduLinq post per maggiori dettagli.

+0

Grazie! Un po 'contro-intuitivo, ma ha senso – hehewaffles

+0

Il link al blog di Jon Skeet sembra essere rotto. Ecco un altro: http://edulinq.googlecode.com/hg/posts/33-CastAndOfType.html –

+0

@TylerGill, anche questo link è rotto – 3per