Когда вы указываете явный тип переменной диапазона, компилятор вставляет вызов Cast<T>. Итак, это:
bool result = (from Match m in matches
where m.Groups["name"].Value.Length > 128
select m).Any();
в точности эквивалентен:
bool result = matches.Cast<Match>()
.Where(m => m.Groups["name"].Value.Length > 128)
.Any();
который также можно записать как:
bool result = matches.Cast<Match>()
.Any(m => m.Groups["name"].Value.Length > 128);
В этом случае Castвызов необходим, потому что MatchCollectionреализует только ICollectionand IEnumerable, а не IEnumerable<T>. Практически все методы расширения LINQ to Objects нацелены на IEnumerable<T>, за заметными исключениями Castи OfType, оба из которых используются для преобразования «слабо» типизированной коллекции (например, MatchCollection) в универсальную, IEnumerable<T>которая затем позволяет выполнять дальнейшие операции LINQ.