UPDATE
Сначала я неправильно понял вопрос; Решение проблемы - скачать Dynamic Linq и ссылаться на него. Ниже я оставлю свой ответ, в котором рассматриваются побочные вопросы, которые вы задавали о типовых методах расширения.
var selectData = (from i in data
select i).Where(d => d.Name=="Bob1");
Но почему бы не это:
var selectData = data.Where(d => d.Name=="Bob1");
Что касается "неуниверсальной" версии where, такой вещи не существует. В приведенных выше вызовах параметр типа универсального метода является неявным; это было выведено компилятором, который компилирует вызов точно так, как он скомпилирует это:
var selectData = data.Where<SomeData>(d => d.Name=="Bob1");
Возможно, эскизная реализация метода Where
поможет уменьшить путаницу с параметром TSource
:
public static IEnumerable<TSource> Where(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
foreach (TSource item in source)
if (predicate(item))
yield return item;
}
TSource
- это тип элемента последовательности, которую вы запрашиваете. Это также тип элемента последовательности результатов.
Компилятору необходимо знать тип по крайней мере по двум причинам:
Во-первых, нам нужно вызвать функцию для каждого элемента, чтобы определить, включать ли его в последовательность результатов. Компилятор должен знать, что референт параметра predicate
может безопасно принимать параметр типа TSource.
Вторая причина в этом случае несколько тривиальна; item
должно быть совместимо с присваиванием с TSource
, потому что оно используется в операторе yield return
. Конечно, оно совместимо, потому что оно того же типа.