3
  1. Why is there a non-generic IQueryable when there's a generic one? Could you please provide a use for it?

  2. Isn't the ElementType member of the non-generic IQueryable interface redundant for the same reason?

The two IQueryable interfaces were introduced well after generics had been introduced. So, having both the generic and non-generic version does not look like an evolutionary progression as is the case with IEnumerable and its generic version.

Surely, Microsoft must have had a strong reason to keep both of the interfaces?

svick
  • 236,525
  • 50
  • 385
  • 514
Prakash
  • 71
  • 5
  • Related: https://stackoverflow.com/questions/56375/are-non-generic-collections-in-net-obsolete – Chris Jan 24 '15 at 15:40
  • http://stackoverflow.com/questions/18535017/iqueryable-vs-iqueryablet – The One Jan 24 '15 at 15:41
  • 2
    Look at it as a shorthand for `IQueryable` and no more – SimpleVar Jan 24 '15 at 15:42
  • 2
    I read Matt Warren's series on building a LINQ provider and I am not sure what he means by the expression, "*dynamic query building scenarios*" when he says, "The generic IQueryable is the one you use most often in method signatures and the like. The non-generic IQueryable exist primarily to give you a weakly typed entry point primarily for dynamic query building scenarios." – Prakash Jan 24 '15 at 15:52
  • I strongly disagree with @YoryeNathan comment. See my answer. – Chad Carisch Feb 09 '15 at 13:43

1 Answers1

2

The main purpose of this interface is to allow access to the ElementType, Expression, and Provider without needing to know the Generic Type.

This is a fairly common practice for Microsoft when writing Generic Types. List<T> inherits from IList<T> which inherits from IList.

In other words you want to expose any property that does not require the generic type in a non generic way. In the case of IQueryable<T> there is not properties exposed. However, the generic type T allows for strongly typed extension methods, that are found in System.Linq.Queryable.

Observe the following:

void Main()
{
    var lst = new List<string>();
    lst.Add("test1");
    lst.Add("test2");
    lst.Add("test3");

    IQueryable<string> q = lst.AsQueryable();

    PrintQueryInfo(  q.Where(x=>x.Contains('1')));

}

public void PrintQueryInfo(IQueryable q){
    Console.WriteLine(q.Expression.ToString());
}

Output:

System.Collections.Generic.List`1[System.String].Where(x => x.Contains(1))

Its also worth noting that the above example could also be done with a generic method. But this is not always possible or practical.

public void PrintQueryInfo<T>(IQueryable<T> q){
    Console.WriteLine(q.Expression.ToString());
}
Chad Carisch
  • 2,422
  • 3
  • 22
  • 30