Если я приведу IQueryable как IEnumerable, тогда вызову метод расширения Linq, какая реализация будет вызвана?

Учитывая следующий код:

IQueryable<T> queryable;

// something to instantiate queryable

var enumerable = (IEnumerable<T>) queryable;

var filtered = enumerable.Where(i => i > 3);

Какой метод расширения вызывается в последней строке?

Это IEnumerable . Где (...) ? Или IQueryable .Where (...) будет вызываться, потому что фактическая реализация, очевидно, все еще является запрашиваемой?

По-видимому, идеальным вариантом будет вызов версии 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".

15
задан James Morcom 7 January 2011 в 13:19
поделиться