Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

If I cast an IQueryable as an IEnumerable then call a Linq extension method, which implementation gets called?

Considering the following code:

IQueryable<T> queryable;

// something to instantiate queryable

var enumerable = (IEnumerable<T>) queryable;

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

In the final line, which extension method gets called?

Is it IEnumerable<T>.Where(...)? Or will IQueryable<T>.Where(...) be called because the actual implementation is still obviously a queryable?

Presumably the ideal would be for the IQueryable version to be called, in the same way that normal polymorphism will always use the more specific override.

In Visual Studio though when I right-click on the Where method and "Go to Definition" I'm taken to the IEnumerable version, which kind of makes sense from a visual point-of-view.

My main concern is that if somewhere in my app I use Linq to NHibernate to get a Queryable, but I pass it around using an interface that uses the more general IEnumerable signature, I'll lose the wonders of deferred database execution!


Edit: It turns out that, as Iridium has pointed out, it's the Enumerable version that gets called

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";
        }
    }

The output is "MyString method".

like image 707
James Morcom Avatar asked Jan 07 '11 12:01

James Morcom


People also ask

What is extension method in LINQ?

LinqExtensionMethod.zip. Linq provides standard query operators like filtering, sorting, grouping, aggregation, and concatenations, and it has many operators to achive many types of functionalities, which are called extension methods, in LINQ.

When should I use IQueryable and IEnumerable using LINQ?

In LINQ to query data from database and collections, we use IEnumerable and IQueryable for data manipulation. IEnumerable is inherited by IQueryable, Hence IQueryable has all the features of IEnumerable and except this, it has its own features. Both have its own importance to query data and data manipulation.

How LINQ is implemented?

The way providers such as LINQ to SQL work is generally via the Queryable class. At their core, they translate expression trees into other query formats, and then construct appropriate objects with the results of executing those out-of-process queries.

What is the difference between IEnumerable T and IQueryable T >? And how do you switch between them?

The main difference between IEnumerable and IQueryable in C# is that IQueryable queries out-of-memory data stores, while IEnumerable queries in-memory data. Moreover, IQueryable is part of . NET's System. LINQ namespace, while IEnumerable is in System.


1 Answers

The currently accepted answer deals with virtual methods, not extension methods.

If you cast an IQueryable to an IEnumerable and then call one of the extension methods (e.g. Where(...) in your question), then the one on Enumerable version will be called, not the Queryable one.

like image 191
Iridium Avatar answered Sep 30 '22 17:09

Iridium