如果我将一个IQueryable转换为IEnumerable,那么调用一个Linq扩展方法,该实现被调用?

Jam*_*com 15 c# linq extension-methods

考虑以下代码:

IQueryable<T> queryable;

// something to instantiate queryable

var enumerable = (IEnumerable<T>) queryable;

var filtered = enumerable.Where(i => i > 3);
Run Code Online (Sandbox Code Playgroud)

在最后一行中,调用哪个扩展方法?

IEnumerable<T>.Where(...)吗?或者会IQueryable<T>.Where(...)被调用,因为实际的实现仍然显然是可查询的?

据推测,理想的是可以调用IQueryable版本,就像普通多态将始终使用更具体的覆盖一样.

在Visual Studio中,当我右键单击Where方法并"转到定义"时,我被带到IEnumerable版本,从视觉角度来看这是有意义的.

我主要担心的是,如果在我的应用程序的某个地方,我使用Linq到NHibernate来获取Queryable,但是我使用一个使用更通用的IEnumerable签名的接口传递它,我将失去延迟数据库执行的奇迹!


编辑:事实证明,正如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";
        }
    }
Run Code Online (Sandbox Code Playgroud)

输出是"MyString方法".

Iri*_*ium 9

当前接受的答案涉及虚拟方法,而不是扩展方法.

如果将一个IQueryable转换为IEnumerable,然后调用其中一个扩展方法(例如问题中的Where(...)),那么将调用Enumerable版本上的那个,而不是Queryable.