Если у меня есть переменная типа IQueryable
, у меня есть четыре метода расширения для Where
в пространстве имен Systm.Linq
, доступных:
public static IQueryable Where(this IQueryable source,
Expression> predicate);
public static IQueryable Where(this IQueryable source,
Expression> predicate);
public static IEnumerable Where(this IEnumerable source,
Func predicate);
public static IEnumerable Where(this IEnumerable source,
Func predicate);
(Последние два, потому что IQueryable
наследуется от IEnumerable
.)
Если я использую переменную типаObjectQuery
(в пространстве именSystem.Data.Objects
)У меня есть пять доступных перегрузок Where
, а именно четыре выше (, потому что ObjectQuery
реализует IQueryable
и IEnumerable
среди других интерфейсов )и, кроме того, метод экземпляра этого класса:
public ObjectQuery Where(string predicate,
params ObjectParameter[] parameters);
Если я делаю одну и ту же ошибку программирования при использовании IQueryable
или ObjectQuery
, я получаю очень разные ошибки компилятора. Вот пример программы (стандартный шаблон консольного приложения C #в сборке VS2010 SP1 + System.Data.Entity.dll
, добавленный в ссылки на проект, ошибка компилятора находится в комментарии под четырьмя примерами):
using System.Data.Objects;
using System.Linq;
namespace OverloadTest
{
public class Test
{
public int Id { get; set; }
}
class Program
{
static void Main(string[] args)
{
IQueryable queryable = null;
ObjectQuery objectQuery = null;
var query1 = queryable.Where(t => t.Name == "XYZ");
// no definition for "Name" in class OverloadTest.Test
var query2 = queryable.Where(t => bla == blabla);
// "bla", "blabla" do not exist in current context
var query3 = objectQuery.Where(t => t.Name == "XYZ");
// Delegate System.Func
// does not take 1 argument
var query4 = objectQuery.Where(t => bla == blabla);
// Delegate System.Func
// does not take 1 argument
}
}
}
"Закорючки" в компиляторе тоже выглядят иначе:
Я понимаю первые две ошибки. Но почему компилятор явно хочет использовать перегрузку номер 4 (сFunc
)в последних двух примерах и не говорит мне, что «Имя» не определено в классе Test
и что «бла» и «блабла» не существуют в текущем контексте?
Я ожидал, что компилятор сможет безопасно исключить перегрузку № 5 (Я не передаю string
в качестве параметра )и перегрузку № 2 и 4 (Я не передаю лямбда-выражение с два параметра(t,i) =>...
)но мое ожидание не кажется правильным.
В качестве примечания :я столкнулся с этой проблемой, просматривая этот вопрос . Спрашивающий сказал там, что четвертый запрос в вопросе не компилируется (он имеет точно такую же ошибку компилятора в примере № 3 и 4 выше ),но этот запрос как раз и есть решение его проблемы и мне кажется что-то (переменная или имя свойства? )написано неправильно в запросе (он не подтвердил это, хотя )но эта ошибка компилятора не дает полезного указания на то, что не так.
Изменить
Ссылаясь на очень полезный комментарий Мартина Харриса ниже:
В примере query4
ошибка «Delegate System.Func не принимает 1 аргумент » — это ошибка, отображаемая в окне всплывающей подсказки при наведении указателя мыши на волнистую линию. В окне вывода компилятора на самом деле четыре ошибки в этом порядке:
Но почему компилятор не жалуется на первую ошибку для первых двух примеров, использующих IQueryable
?