IQueryable Vs Queryable X IEnumerable Vs Enumerable Vs IEnumerator X IList Vs List

In this article, we will learn the differences and importance of each one - IQueryable, Queryable, IEnumerable, Enumerable, Enumerator, IList, and List.

This is very common for beginners to get fuzzy with these words in their head. These are all alike and seem to be used for the same purpose. Well, let us see how all these are different.

Do they have the same purpose? In some ways, they do have the same purpose, but there are some differences also and we are going through the differences and similarities here in this article below.
 
Let us start with the types that start with an "I". They represent the interface, while their implementation are the classes that do not start with "I".
 
Interface Implementation
IList List
IQueryable Queryable
IEnumerator
IEnumarable Enumerable
 
With the exception of the IQueryable / Queryable which derives from LINQ, they all derive from C# collections, along with many other types.

What is an interface?

 
An interface contains the signature of methods, properties, events, and indexers that are going to have their behavior implemented in the classes that inherit from it.
 
Example of an interface and its implementation -
  1. interface ISample  
  2. {  
  3.     void AnyMethod();  
  4. }  
  5.   
  6. class Sample : ISample  
  7. {  
  8.     // Interface member implementation:   
  9.     void AnyMethod()  
  10.     {  
  11.         // The method implementation.  
  12.     }  
  13.   
  14.     static void Main()  
  15.     {  
  16.         // Declare an interface instance.  
  17.         ISample obj = new Sample();  
  18.   
  19.         // Call the member.  
  20.         obj.AnyMethod();  
  21.     }  
  22. }  
 

Benefits of using Interfaces

 
You may feel that it is a waste of time to create interfaces but here is why it is important.
  • Decoupling, reducing dependency from implementation classes; 
  • Readability, as an interface implements the signature of your code their name must make sense with their purpose;
  • Maintainability, making it possible of having different implementations based on the same interface;
  • Extensibility, being easier to extend classes with a different implementation based on the same contract.

IQueryable vs IEnumarable vs IEnumerator vs IList

 
IQueryable
 
Inherits from IEnumerable and has this signature -
  1. using System.Collections;  
  2. using System.Linq.Expressions;  
  3.   
  4. namespace System.Linq  
  5. {  
  6.     //  
  7.     // Summary:  
  8.     //     Provides functionality to evaluate queries against a specific data source wherein  
  9.     //     the type of the data is not specified.  
  10.     public interface IQueryable : IEnumerable  
  11.     {  
  12.         //  
  13.         // Summary:  
  14.         //     Gets the type of the element(s) that are returned when the expression tree associated  
  15.         //     with this instance of System.Linq.IQueryable is executed.  
  16.         //  
  17.         // Returns:  
  18.         //     A System.Type that represents the type of the element(s) that are returned when  
  19.         //     the expression tree associated with this object is executed.  
  20.         Type ElementType { get; }  
  21.         //  
  22.         // Summary:  
  23.         //     Gets the expression tree that is associated with the instance of System.Linq.IQueryable.  
  24.         //  
  25.         // Returns:  
  26.         //     The System.Linq.Expressions.Expression that is associated with this instance  
  27.         //     of System.Linq.IQueryable.  
  28.         Expression Expression { get; }  
  29.         //  
  30.         // Summary:  
  31.         //     Gets the query provider that is associated with this data source.  
  32.         //  
  33.         // Returns:  
  34.         //     The System.Linq.IQueryProvider that is associated with this data source.  
  35.         IQueryProvider Provider { get; }  
  36.     }  
  37. }  
 
IEnumerable
 
Exposes the enumerator which supports a simple iteration over a collection of a specified type.
  1. namespace System.Collections.Generic  
  2. {  
  3.     //  
  4.     // Summary:  
  5.     //     Exposes the enumerator, which supports a simple iteration over a collection of  
  6.     //     a specified type.  
  7.     //  
  8.     // Type parameters:  
  9.     //   T:  
  10.     //     The type of objects to enumerate.  
  11.     public interface IEnumerable<out T> : IEnumerable  
  12.     {  
  13.         //  
  14.         // Summary:  
  15.         //     Returns an enumerator that iterates through the collection.  
  16.         //  
  17.         // Returns:  
  18.         //     An enumerator that can be used to iterate through the collection.  
  19.         IEnumerator<T> GetEnumerator();  
  20.     }  
  21. }  
 
IEnumerator
 
Supports a simple iteration over a generic collection and does not have an implementation like the other interfaces. It is better used for iteration over generic collections, like when using a foreach statement. 
  1. namespace System.Collections.Generic  
  2. {  
  3.     //  
  4.     // Summary:  
  5.     //     Supports a simple iteration over a generic collection.  
  6.     //  
  7.     // Type parameters:  
  8.     //   T:  
  9.     //     The type of objects to enumerate.  
  10.     public interface IEnumerator<out T> : IEnumerator, IDisposable  
  11.     {  
  12.         //  
  13.         // Summary:  
  14.         //     Gets the element in the collection at the current position of the enumerator.  
  15.         //  
  16.         // Returns:  
  17.         //     The element in the collection at the current position of the enumerator.  
  18.         T Current { get; }  
  19.     }  
  20. }  
A deeper explanation with a nice example can be found here.

IList

It inherits from ICollection and IEnumerable, representing a collection of objects that can be individually accessed by index.
  1. using System.Reflection;  
  2.   
  3. namespace System.Collections.Generic  
  4. {  
  5.     //  
  6.     // Summary:  
  7.     //     Represents a collection of objects that can be individually accessed by index.  
  8.     //  
  9.     // Type parameters:  
  10.     //   T:  
  11.     //     The type of elements in the list.  
  12.     [DefaultMember( "Item" )]  
  13.     public interface IList<T> : ICollection<T>, IEnumerable<T>, IEnumerable  
  14.     {  
  15.         //  
  16.         // Summary:  
  17.         //     Gets or sets the element at the specified index.  
  18.         //  
  19.         // Parameters:  
  20.         //   index:  
  21.         //     The zero-based index of the element to get or set.  
  22.         //  
  23.         // Returns:  
  24.         //     The element at the specified index.  
  25.         //  
  26.         // Exceptions:  
  27.         //   T:System.ArgumentOutOfRangeException:  
  28.         //     index is not a valid index in the System.Collections.Generic.IList`1.  
  29.         //  
  30.         //   T:System.NotSupportedException:  
  31.         //     The property is set and the System.Collections.Generic.IList`1 is read-only.  
  32.         T this[int index] { getset; }  
  33.   
  34.         //  
  35.         // Summary:  
  36.         //     Determines the index of a specific item in the System.Collections.Generic.IList`1.  
  37.         //  
  38.         // Parameters:  
  39.         //   item:  
  40.         //     The object to locate in the System.Collections.Generic.IList`1.  
  41.         //  
  42.         // Returns:  
  43.         //     The index of item if found in the list; otherwise, -1.  
  44.         int IndexOf( T item );  
  45.         //  
  46.         // Summary:  
  47.         //     Inserts an item to the System.Collections.Generic.IList`1 at the specified index.  
  48.         //  
  49.         // Parameters:  
  50.         //   index:  
  51.         //     The zero-based index at which item should be inserted.  
  52.         //  
  53.         //   item:  
  54.         //     The object to insert into the System.Collections.Generic.IList`1.  
  55.         //  
  56.         // Exceptions:  
  57.         //   T:System.ArgumentOutOfRangeException:  
  58.         //     index is not a valid index in the System.Collections.Generic.IList`1.  
  59.         //  
  60.         //   T:System.NotSupportedException:  
  61.         //     The System.Collections.Generic.IList`1 is read-only.  
  62.         void Insert( int index, T item );  
  63.         //  
  64.         // Summary:  
  65.         //     Removes the System.Collections.Generic.IList`1 item at the specified index.  
  66.         //  
  67.         // Parameters:  
  68.         //   index:  
  69.         //     The zero-based index of the item to remove.  
  70.         //  
  71.         // Exceptions:  
  72.         //   T:System.ArgumentOutOfRangeException:  
  73.         //     index is not a valid index in the System.Collections.Generic.IList`1.  
  74.         //  
  75.         //   T:System.NotSupportedException:  
  76.         //     The System.Collections.Generic.IList`1 is read-only.  
  77.         void RemoveAt( int index );  
  78.     }  
  79. }   
 

Queryable vs Enumarable vs List

Queryable 

  • Namespace: System.LinQ;
  • Implements and most of its methods extends IQueryable;
  • Good for Query data in LinQ. Like to filter data;
  • The query is deferred, being executed when those values are needed;
  • Usage for LinQ to SQL 
 
Enumerable
  • Namespace: System.LinQ;
  • Implements and most of its methods extends IEnumerable;
  • Good for querying data from the in-memory collection, like list or array;
  • The query is deferred, being executed when the object is enumerated.
  • Usage for LINQ to Object and LINQ to XML;
 
List
  • Namespace: System.Collections.Generic;
  • Inherits from: ICollection<T>, IEnumerable<T>, IEnumerable, IList<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection, IList;
  • Good for interaction within in-memory objects. Like to update, remove or include items. 
  • The query is executed immediately, allocating the result in memory. 
 

External References