Merge pull request #487 from mayerwin/patch-1
[mono.git] / mcs / class / System.Core / System.Linq / Queryable.cs
index f52d21d1c9ab163ddba0e5d675241003ad55c6e0..e9b98cca9e1e536efeaa264195820cc503e3654f 100644 (file)
 //
 
 using System;
+using System.Collections;
 using System.Collections.Generic;
 using System.Linq.Expressions;
 using System.Reflection;
 using System.Linq;
 
-namespace System.Linq
-{
+namespace System.Linq {
 
-       public static class Queryable
-       {
+       public static class Queryable {
 
                static MethodInfo MakeGeneric (MethodBase method, params Type [] parameters)
                {
@@ -75,23 +74,23 @@ namespace System.Linq
                {
                        Check.SourceAndFunc (source, func);
                        return source.Provider.Execute<TAccumulate> (
-               StaticCall (
-                       MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource), typeof (TAccumulate)),
-                       source.Expression,
-                       Expression.Constant (seed),
-                       Expression.Quote (func)));
+                               StaticCall (
+                                       MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource), typeof (TAccumulate)),
+                                       source.Expression,
+                                       Expression.Constant (seed, typeof (TAccumulate)),
+                                       Expression.Quote (func)));
                }
 
                public static TResult Aggregate<TSource, TAccumulate, TResult> (this IQueryable<TSource> source, TAccumulate seed, Expression<Func<TAccumulate, TSource, TAccumulate>> func, Expression<Func<TAccumulate, TResult>> selector)
                {
                        Check.SourceAndFuncAndSelector (source, func, selector);
                        return source.Provider.Execute<TResult> (
-               StaticCall (
-                       MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource), typeof (TAccumulate), typeof (TResult)),
-                       source.Expression,
-                       Expression.Constant (seed),
-                       Expression.Quote (func),
-                       Expression.Quote (selector)));
+                               StaticCall (
+                                       MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource), typeof (TAccumulate), typeof (TResult)),
+                                       source.Expression,
+                                       Expression.Constant (seed, typeof (TAccumulate)),
+                                       Expression.Quote (func),
+                                       Expression.Quote (selector)));
                }
 
                #endregion
@@ -140,75 +139,92 @@ namespace System.Linq
 
                public static IQueryable<TElement> AsQueryable<TElement> (this IEnumerable<TElement> source)
                {
-                       if (source is IQueryable<TElement>)
-                               return (IQueryable<TElement>) source;
-                       throw new NotImplementedException ();
+                       if (source == null)
+                               throw new ArgumentNullException ("source");
+
+                       var queryable = source as IQueryable<TElement>;
+                       if (queryable != null)
+                               return queryable;
+
+                       return new QueryableEnumerable<TElement> (source);
                }
 
-               public static IQueryable AsQueryable (this IQueryable source)
+               public static IQueryable AsQueryable (this IEnumerable source)
                {
-                       throw new NotImplementedException ();
+                       if (source == null)
+                               throw new ArgumentNullException ("source");
+
+                       var queryable = source as IQueryable;
+                       if (queryable != null)
+                               return queryable;
+
+                       Type ienumerable;
+                       if (!source.GetType ().IsGenericImplementationOf (typeof (IEnumerable<>), out ienumerable))
+                               throw new ArgumentException ("source is not IEnumerable<>");
+
+                       return (IQueryable) Activator.CreateInstance (
+                               typeof (QueryableEnumerable<>).MakeGenericType (ienumerable.GetFirstGenericArgument ()), source);
                }
 
                #endregion
 
                #region Average
 
-               public static int Average (this IQueryable<int> source)
+               public static double Average (this IQueryable<int> source)
                {
                        Check.Source (source);
 
-                       return source.Provider.Execute<int> (
+                       return source.Provider.Execute<double>(
                                StaticCall (
                                        (MethodInfo) MethodBase.GetCurrentMethod (),
                                        source.Expression));
                }
 
-               public static int? Average (this IQueryable<int?> source)
+               public static double? Average(this IQueryable<int?> source)
                {
                        Check.Source (source);
 
-                       return source.Provider.Execute<int?> (
+                       return source.Provider.Execute<double?>(
                                StaticCall (
                                        (MethodInfo) MethodBase.GetCurrentMethod (),
                                        source.Expression));
                }
 
-               public static long Average (this IQueryable<long> source)
+               public static double Average(this IQueryable<long> source)
                {
                        Check.Source (source);
 
-                       return source.Provider.Execute<long> (
+                       return source.Provider.Execute<double>(
                                StaticCall (
                                        (MethodInfo) MethodBase.GetCurrentMethod (),
                                        source.Expression));
                }
 
-               public static long? Average (this IQueryable<long?> source)
+               public static double? Average(this IQueryable<long?> source)
                {
                        Check.Source (source);
 
-                       return source.Provider.Execute<long?> (
+                       return source.Provider.Execute<double?>(
                                StaticCall (
                                        (MethodInfo) MethodBase.GetCurrentMethod (),
                                        source.Expression));
                }
 
-               public static float Average (this IQueryable<float> source)
+               public static float Average(this IQueryable<float> source)
                {
                        Check.Source (source);
 
-                       return source.Provider.Execute<float> (
+                       return source.Provider.Execute<float>(
                                StaticCall (
-                                       (MethodInfo) (MethodInfo) MethodBase.GetCurrentMethod (),
+                                       (MethodInfo) MethodBase.GetCurrentMethod (),
                                        source.Expression));
                }
 
-               public static float? Average (this IQueryable<float?> source)
+               public static float? Average(this IQueryable<float?> source)
                {
                        Check.Source (source);
 
-                       return source.Provider.Execute<float?> (
+                       return source.Provider.Execute<float?>(
                                StaticCall (
                                        (MethodInfo) MethodBase.GetCurrentMethod (),
                                        source.Expression));
@@ -234,86 +250,86 @@ namespace System.Linq
                                        source.Expression));
                }
 
-               public static decimal Average (this IQueryable<decimal> source)
+               public static decimal Average(this IQueryable<decimal> source)
                {
                        Check.Source (source);
 
-                       return source.Provider.Execute<decimal> (
+                       return source.Provider.Execute<decimal>(
                                StaticCall (
                                (MethodInfo) MethodBase.GetCurrentMethod (),
                                        source.Expression));
                }
 
-               public static decimal? Average (this IQueryable<decimal?> source)
+               public static decimal? Average(this IQueryable<decimal?> source)
                {
                        Check.Source (source);
 
-                       return source.Provider.Execute<decimal?> (
+                       return source.Provider.Execute<decimal?>(
                                StaticCall (
                                        (MethodInfo) MethodBase.GetCurrentMethod (),
                                        source.Expression));
                }
 
-               public static int Average<TSource> (this IQueryable<TSource> source, Expression<Func<TSource, int>> selector)
+               public static double Average<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, int>> selector)
                {
                        Check.SourceAndSelector (source, selector);
 
-                       return source.Provider.Execute<int> (
+                       return source.Provider.Execute<double>(
                                StaticCall (
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
                                        source.Expression,
                                        Expression.Quote (selector)));
                }
 
-               public static int? Average<TSource> (this IQueryable<TSource> source, Expression<Func<TSource, int?>> selector)
+               public static double? Average<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, int?>> selector)
                {
                        Check.SourceAndSelector (source, selector);
 
-                       return source.Provider.Execute<int?> (
+                       return source.Provider.Execute<double?>(
                                StaticCall (
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
                                        source.Expression,
                                        Expression.Quote (selector)));
                }
 
-               public static long Average<TSource> (this IQueryable<TSource> source, Expression<Func<TSource, long>> selector)
+               public static double Average<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, long>> selector)
                {
                        Check.SourceAndSelector (source, selector);
 
-                       return source.Provider.Execute<long> (
+                       return source.Provider.Execute<double>(
                                StaticCall (
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
                                        source.Expression,
                                        Expression.Quote (selector)));
                }
 
-               public static long? Average<TSource> (this IQueryable<TSource> source, Expression<Func<TSource, long?>> selector)
+               public static double? Average<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, long?>> selector)
                {
                        Check.SourceAndSelector (source, selector);
 
-                       return source.Provider.Execute<long?> (
+                       return source.Provider.Execute<double?>(
                                StaticCall (
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
                                        source.Expression,
                                        Expression.Quote (selector)));
                }
 
-               public static float Average<TSource> (this IQueryable<TSource> source, Expression<Func<TSource, float>> selector)
+               public static float Average<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, float>> selector)
                {
                        Check.SourceAndSelector (source, selector);
 
-                       return source.Provider.Execute<float> (
+                       return source.Provider.Execute<float>(
                                StaticCall (
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
                                        source.Expression,
                                        Expression.Quote (selector)));
                }
 
-               public static float? Average<TSource> (this IQueryable<TSource> source, Expression<Func<TSource, float?>> selector)
+               public static float? Average<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, float?>> selector)
                {
                        Check.SourceAndSelector (source, selector);
 
-                       return source.Provider.Execute<float?> (
+                       return source.Provider.Execute<float?>(
                                StaticCall (
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
                                        source.Expression,
@@ -342,22 +358,22 @@ namespace System.Linq
                                        Expression.Quote (selector)));
                }
 
-               public static decimal Average<TSource> (this IQueryable<TSource> source, Expression<Func<TSource, decimal>> selector)
+               public static decimal Average<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, decimal>> selector)
                {
                        Check.SourceAndSelector (source, selector);
 
-                       return source.Provider.Execute<decimal> (
+                       return source.Provider.Execute<decimal>(
                                StaticCall (
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
                                        source.Expression,
                                        Expression.Quote (selector)));
                }
 
-               public static decimal? Average<TSource> (this IQueryable<TSource> source, Expression<Func<TSource, decimal?>> selector)
+               public static decimal? Average<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, decimal?>> selector)
                {
                        Check.SourceAndSelector (source, selector);
 
-                       return source.Provider.Execute<decimal?> (
+                       return source.Provider.Execute<decimal?>(
                                StaticCall (
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
                                        source.Expression,
@@ -389,7 +405,7 @@ namespace System.Linq
                                StaticCall (
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
                                        source1.Expression,
-                                       Expression.Constant (source2)));
+                                       Expression.Constant (source2, typeof (IEnumerable<TSource>))));
                }
 
                #endregion
@@ -404,7 +420,7 @@ namespace System.Linq
                                StaticCall (
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
                                        source.Expression,
-                                       Expression.Constant (item)));
+                                       Expression.Constant (item, typeof (TSource))));
                }
 
                public static bool Contains<TSource> (this IQueryable<TSource> source, TSource item, IEqualityComparer<TSource> comparer)
@@ -415,8 +431,8 @@ namespace System.Linq
                                StaticCall (
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
                                        source.Expression,
-                                       Expression.Constant (item),
-                                       Expression.Constant (comparer)));
+                                       Expression.Constant (item, typeof (TSource)),
+                                       Expression.Constant (comparer, typeof (IEqualityComparer<TSource>))));
                }
 
                #endregion
@@ -463,7 +479,7 @@ namespace System.Linq
                                StaticCall (
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
                                        source.Expression,
-                                       Expression.Constant (defaultValue)));
+                                       Expression.Constant (defaultValue, typeof (TSource))));
                }
 
                #endregion
@@ -488,7 +504,7 @@ namespace System.Linq
                                StaticCall (
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
                                        source.Expression,
-                                       Expression.Constant (comparer)));
+                                       Expression.Constant (comparer, typeof (IEqualityComparer<TSource>))));
                }
 
                #endregion
@@ -533,7 +549,7 @@ namespace System.Linq
                                StaticCall (
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
                                        source1.Expression,
-                                       Expression.Constant (source2)));
+                                       Expression.Constant (source2, typeof (IEnumerable<TSource>))));
                }
 
                public static IQueryable<TSource> Except<TSource> (this IQueryable<TSource> source1, IEnumerable<TSource> source2, IEqualityComparer<TSource> comparer)
@@ -544,8 +560,8 @@ namespace System.Linq
                                StaticCall (
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
                                        source1.Expression,
-                                       Expression.Constant (source2),
-                                       Expression.Constant (comparer)));
+                                       Expression.Constant (source2, typeof (IEnumerable<TSource>)),
+                                       Expression.Constant (comparer, typeof (IEqualityComparer<TSource>))));
                }
 
                #endregion
@@ -621,13 +637,13 @@ namespace System.Linq
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource), typeof (TKey)),
                                        source.Expression,
                                        Expression.Quote (keySelector),
-                                       Expression.Constant (comparer)));
+                                       Expression.Constant (comparer, typeof (IEqualityComparer<TKey>))));
                }
-               public static IQueryable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey, TElement> (this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, Expression<Func<TSource, TElement>> elementSelector)
+               public static IQueryable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement> (this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, Expression<Func<TSource, TElement>> elementSelector)
                {
                        Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
 
-                       return source.Provider.CreateQuery<IGrouping<TKey, TSource>> (
+                       return source.Provider.CreateQuery<IGrouping<TKey, TElement>>(
                                StaticCall (
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource), typeof (TKey), typeof (TElement)),
                                        source.Expression,
@@ -655,7 +671,7 @@ namespace System.Linq
                                        source.Expression,
                                        Expression.Quote (keySelector),
                                        Expression.Quote (elementSelector),
-                                       Expression.Constant (comparer)));
+                                       Expression.Constant (comparer, typeof (IEqualityComparer<TKey>))));
                }
                public static IQueryable<TResult> GroupBy<TSource, TKey, TElement, TResult> (this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, Expression<Func<TSource, TElement>> elementSelector, Expression<Func<TKey, IEnumerable<TElement>, TResult>> resultSelector)
                {
@@ -680,7 +696,7 @@ namespace System.Linq
                                        source.Expression,
                                        Expression.Quote (keySelector),
                                        Expression.Quote (resultSelector),
-                                       Expression.Constant (comparer)));
+                                       Expression.Constant (comparer, typeof (IEqualityComparer<TKey>))));
                }
                public static IQueryable<TResult> GroupBy<TSource, TKey, TElement, TResult> (this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, Expression<Func<TSource, TElement>> elementSelector, Expression<Func<TKey, IEnumerable<TElement>, TResult>> resultSelector, IEqualityComparer<TKey> comparer)
                {
@@ -693,7 +709,7 @@ namespace System.Linq
                                        Expression.Quote (keySelector),
                                        Expression.Quote (elementSelector),
                                        Expression.Quote (resultSelector),
-                                       Expression.Constant (comparer)));
+                                       Expression.Constant (comparer, typeof (IEqualityComparer<TKey>))));
                }
                #endregion
 
@@ -716,7 +732,7 @@ namespace System.Linq
                                StaticCall (
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TOuter), typeof (TInner), typeof (TKey), typeof (TResult)),
                                        outer.Expression,
-                                       Expression.Constant (inner),
+                                       Expression.Constant (inner, typeof (IEnumerable<TInner>)),
                                        Expression.Quote (outerKeySelector),
                                        Expression.Quote (innerKeySelector),
                                        Expression.Quote (resultSelector)));
@@ -739,7 +755,7 @@ namespace System.Linq
                                StaticCall (
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TOuter), typeof (TInner), typeof (TKey), typeof (TResult)),
                                        outer.Expression,
-                                       Expression.Constant (inner),
+                                       Expression.Constant (inner, typeof (IEnumerable<TInner>)),
                                        Expression.Quote (outerKeySelector),
                                        Expression.Quote (innerKeySelector),
                                        Expression.Quote (resultSelector),
@@ -758,7 +774,7 @@ namespace System.Linq
                                StaticCall (
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
                                        source1.Expression,
-                                       Expression.Constant (source2)));
+                                       Expression.Constant (source2, typeof (IEnumerable<TSource>))));
                }
 
                public static IQueryable<TSource> Intersect<TSource> (this IQueryable<TSource> source1, IEnumerable<TSource> source2, IEqualityComparer<TSource> comparer)
@@ -769,8 +785,8 @@ namespace System.Linq
                                StaticCall (
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
                                        source1.Expression,
-                                       Expression.Constant (source2),
-                                       Expression.Constant (comparer)));
+                                       Expression.Constant (source2, typeof (IEnumerable<TSource>)),
+                                       Expression.Constant (comparer, typeof (IEqualityComparer<TSource>))));
                }
 
                #endregion
@@ -785,7 +801,7 @@ namespace System.Linq
                                StaticCall (
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TOuter), typeof (TInner), typeof (TKey), typeof (TResult)),
                                        outer.Expression,
-                                       Expression.Constant (inner),
+                                       Expression.Constant (inner, typeof (IEnumerable<TInner>)),
                                        Expression.Quote (outerKeySelector),
                                        Expression.Quote (innerKeySelector),
                                        Expression.Quote (resultSelector)));
@@ -799,11 +815,11 @@ namespace System.Linq
                                StaticCall (
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TOuter), typeof (TInner), typeof (TKey), typeof (TResult)),
                                        outer.Expression,
-                                       Expression.Constant (inner),
+                                       Expression.Constant (inner, typeof (IEnumerable<TInner>)),
                                        Expression.Quote (outerKeySelector),
                                        Expression.Quote (innerKeySelector),
                                        Expression.Quote (resultSelector),
-                                       Expression.Constant (comparer)));
+                                       Expression.Constant (comparer, typeof (IEqualityComparer<TKey>))));
                }
 
 
@@ -949,54 +965,54 @@ namespace System.Linq
 
                #region OrderBy
 
-               public static IQueryable<TSource> OrderBy<TSource, TKey> (this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
+               public static IOrderedQueryable<TSource> OrderBy<TSource, TKey> (this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
                {
                        Check.SourceAndKeySelector (source, keySelector);
 
-                       return source.Provider.CreateQuery<TSource> (
+                       return (IOrderedQueryable<TSource>) source.Provider.CreateQuery<TSource> (
                                StaticCall (
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource), typeof (TKey)),
                                        source.Expression,
                                        Expression.Quote (keySelector)));
                }
 
-               public static IQueryable<TSource> OrderBy<TSource, TKey> (this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, IComparer<TKey> comparer)
+               public static IOrderedQueryable<TSource> OrderBy<TSource, TKey> (this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, IComparer<TKey> comparer)
                {
                        Check.SourceAndKeySelector (source, keySelector);
 
-                       return source.Provider.CreateQuery<TSource> (
+                       return (IOrderedQueryable<TSource>) source.Provider.CreateQuery<TSource> (
                                StaticCall (
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource), typeof (TKey)),
                                        source.Expression,
                                        Expression.Quote (keySelector),
-                                       Expression.Constant (comparer)));
+                                       Expression.Constant (comparer, typeof (IComparer<TKey>))));
                }
 
                #endregion
 
                #region OrderByDescending
 
-               public static IQueryable<TSource> OrderByDescending<TSource, TKey> (this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
+               public static IOrderedQueryable<TSource> OrderByDescending<TSource, TKey> (this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
                {
                        Check.SourceAndKeySelector (source, keySelector);
 
-                       return source.Provider.CreateQuery<TSource> (
+                       return (IOrderedQueryable<TSource>) source.Provider.CreateQuery<TSource> (
                                StaticCall (
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource), typeof (TKey)),
                                        source.Expression,
                                        Expression.Quote (keySelector)));
                }
 
-               public static IQueryable<TSource> OrderByDescending<TSource, TKey> (this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, IComparer<TKey> comparer)
+               public static IOrderedQueryable<TSource> OrderByDescending<TSource, TKey> (this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, IComparer<TKey> comparer)
                {
                        Check.SourceAndKeySelector (source, keySelector);
 
-                       return source.Provider.CreateQuery<TSource> (
+                       return (IOrderedQueryable<TSource>) source.Provider.CreateQuery<TSource> (
                                StaticCall (
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource), typeof (TKey)),
                                        source.Expression,
                                        Expression.Quote (keySelector),
-                                       Expression.Constant (comparer)));
+                                       Expression.Constant (comparer, typeof (IComparer<TKey>))));
                }
 
                #endregion
@@ -1101,7 +1117,7 @@ namespace System.Linq
                                StaticCall (
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
                                        source1.Expression,
-                                       Expression.Constant (source2)));
+                                       Expression.Constant (source2, typeof (IEnumerable<TSource>))));
                }
 
                public static bool SequenceEqual<TSource> (this IQueryable<TSource> source1, IEnumerable<TSource> source2, IEqualityComparer<TSource> comparer)
@@ -1112,8 +1128,8 @@ namespace System.Linq
                                StaticCall (
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
                                        source1.Expression,
-                                       Expression.Constant (source2),
-                                       Expression.Constant (comparer)));
+                                       Expression.Constant (source2, typeof (IEnumerable<TSource>)),
+                                       Expression.Constant (comparer, typeof (IEqualityComparer<TSource>))));
                }
 
                #endregion
@@ -1500,7 +1516,7 @@ namespace System.Linq
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource), typeof (TKey)),
                                        source.Expression,
                                        Expression.Quote (keySelector),
-                                       Expression.Constant (comparer)));
+                                       Expression.Constant (comparer, typeof (IComparer<TKey>))));
                }
 
                #endregion
@@ -1527,14 +1543,14 @@ namespace System.Linq
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource), typeof (TKey)),
                                        source.Expression,
                                        Expression.Quote (keySelector),
-                                       Expression.Constant (comparer)));
+                                       Expression.Constant (comparer, typeof (IComparer<TKey>))));
                }
 
                #endregion
 
                #region Union
 
-               public static IEnumerable<TSource> Union<TSource> (this IQueryable<TSource> source1, IEnumerable<TSource> source2)
+               public static IQueryable<TSource> Union<TSource> (this IQueryable<TSource> source1, IEnumerable<TSource> source2)
                {
                        Check.Source1AndSource2 (source1, source2);
 
@@ -1542,10 +1558,10 @@ namespace System.Linq
                                StaticCall (
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
                                        source1.Expression,
-                                       Expression.Constant (source2)));
+                                       Expression.Constant (source2, typeof (IEnumerable<TSource>))));
                }
 
-               public static IEnumerable<TSource> Union<TSource> (this IQueryable<TSource> source1, IEnumerable<TSource> source2, IEqualityComparer<TSource> comparer)
+               public static IQueryable<TSource> Union<TSource>(this IQueryable<TSource> source1, IEnumerable<TSource> source2, IEqualityComparer<TSource> comparer)
                {
                        Check.Source1AndSource2 (source1, source2);
 
@@ -1553,8 +1569,8 @@ namespace System.Linq
                                StaticCall (
                                        MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
                                        source1.Expression,
-                                       Expression.Constant (source2),
-                                       Expression.Constant (comparer)));
+                                       Expression.Constant (source2, typeof (IEnumerable<TSource>)),
+                                       Expression.Constant (comparer, typeof (IEqualityComparer<TSource>))));
                }
 
 
@@ -1587,5 +1603,23 @@ namespace System.Linq
 
                #endregion
 
+#if NET_4_0 || MOONLIGHT || MOBILE
+               #region Zip
+
+               public static IQueryable<TResult> Zip<TFirst, TSecond, TResult> (this IQueryable<TFirst> source1, IEnumerable<TSecond> source2, Expression<Func<TFirst, TSecond, TResult>> resultSelector)
+               {
+                       Check.Source1AndSource2 (source1, source2);
+                       if (resultSelector == null)
+                               throw new ArgumentNullException ("resultSelector");
+
+                       return source1.Provider.CreateQuery<TResult> (
+                               StaticCall (
+                                       MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TFirst), typeof (TSecond), typeof (TResult)),
+                                       source1.Expression,
+                                       Expression.Quote (resultSelector)));
+               }
+
+               #endregion
+#endif
        }
 }