Учитывая следующий код:
IQueryable<T> queryable;
// something to instantiate queryable
var enumerable = (IEnumerable<T>) queryable;
var filtered = enumerable.Where(i => i > 3);
Какой метод расширения вызывается в последней строке?
Это IEnumerable
? Или IQueryable
будет вызываться, потому что фактическая реализация, очевидно, все еще является запрашиваемой?
По-видимому, идеальным вариантом будет вызов версии IQueryable в том же самом способ, которым нормальный полиморфизм всегда будет использовать более конкретное переопределение.
В Visual Studio, однако, когда я щелкаю правой кнопкой мыши метод Where и "Перейти к определению", я попадаю в версию IEnumerable, которая имеет смысл из визуальная точка зрения.
Меня больше всего беспокоит то, что если где-то в моем приложении я использую Linq to NHibernate, чтобы получить Queryable, но я передаю его с помощью интерфейса, который использует более общую подпись IEnumerable, я ' Я потеряю чудеса отложенного выполнения базы данных!
Edit: Оказывается, как указывал Iridium, вызывается именно версия 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 method".