Учитывая следующий код:
IQueryable<T> queryable;
// something to instantiate queryable
var enumerable = (IEnumerable<T>) queryable;
var filtered = enumerable.Where(i => i > 3);
В последней строке, какой метод расширения вызывается?
Это IEnumerable<T>.Where(...)
? Или будет вызываться IQueryable<T>.Where(...)
, потому что фактическая реализация по-прежнему явно доступна для запроса?
Предположительно, идеал был бы для вызываемой версии IQueryable, так же, как обычный полиморфизм всегда будет использовать более специфическое переопределение.
В Visual Studio, хотя, когда я щелкнул правой кнопкой мыши метод Where и "Go to Definition", я попал в версию IEnumerable, что имеет смысл с визуальной точки зрения.
Моя основная проблема заключается в том, что если где-то в моем приложении я использую Linq для NHibernate, чтобы получить Queryable, но я передаю его с помощью интерфейса, который использует более общую подпись IEnumerable, я потеряю чудеса отложенного выполнения базы данных!
Edit: Оказывается, что, как указал Иридиум, это версия Enumerable, получившая название
public class Program
{
static void Main(string[] args)
{
var myString2 = new MyString2();
var myString = (MyString)myString2;
Console.WriteLine(myString.Method());
Console.ReadLine();
}
}
public class MyString {}
public class MyString2 : MyString {}
public static class ExtensionMethods
{
public static string Method(this MyString instance)
{
return "MyString method";
}
public static string Method(this MyString2 instance)
{
return "MyString2 method";
}
}
Вывод - "Метод MyString".