IEnumerable.Cast() против литья в IEnumerable.Select()

Предположим, что у меня есть IEnumerable<int>, и я хочу, чтобы они были преобразованы в их эквивалентные ASCII символы.

Для одного целого числа это будет всего лишь (char)i, поэтому всегда collection.Select(i => (char)i), но я подумал, что использовать tc > t можно collection.Cast().

Может кто-нибудь объяснить, почему я получаю InvalidCastException, когда я использую collection.Cast<char>(), но не с collection.Select(i => (char)i)?

Edit: Интересно, когда я вызываю collection.OfType<char>(), я получаю пустой набор.

Ответ 1

В методах Cast<T> и OfType<T> выполняются только ссылки и преобразования для распаковки. Поэтому они не могут преобразовать один тип значения в другой тип значения.

Методы работают с неродным интерфейсом IEnumerable, поэтому они по существу преобразуются из IEnumerable<object> в IEnumerable<T>. Таким образом, причина, по которой вы не можете использовать Cast<T> для преобразования из IEnumerable<int> в IEnumerable<char>, - та же самая причина, по которой вы не можете вставить коробку int в char.

По существу, Cast<char> в вашем примере терпит неудачу, поскольку выполняется следующее:

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

Подробнее см. Jon Skeet EduLinq для более подробной информации.