How does method overload resolution work (LINQ Where extension method)?
===

If I have a variable of type `IQueryable<T>` I have four extension methods for `Where` in namespace `Systm.Linq` available:

    public static IQueryable<T> Where<T>(this IQueryable<T> source,
        Expression<Func<T, bool>> predicate);
    public static IQueryable<T> Where<T>(this IQueryable<T> source,
        Expression<Func<T, int, bool>> predicate);
    public static IEnumerable<T> Where<T>(this IEnumerable<T> source,
        Func<T, bool> predicate);
    public static IEnumerable<T> Where<T>(this IEnumerable<T> source,
        Func<T, int, bool> predicate);

(The last two because `IQueryable<T>` inherits from `IEnumerable<T>`.)

If I use a variable of type `ObjectQuery<T>` (in namespace `System.Data.Objects`) I have five overloads of `Where` available, namely the four above (because `ObjectQuery<T>` implements `IQueryable<T>` and `IEnumerable<T>` among other interfaces) and in addition an instance method of this class:

    public ObjectQuery<T> Where(string predicate,
        params ObjectParameter[] parameters);

If I do the same programming mistake while using either `IQueryable<T>` or `ObjectQuery<T>` I get very different compiler errors. Here is an example program (standard C# console application template in VS2010 SP1 + `System.Data.Entity.dll` assembly added to project references, the compiler error is in comment below the four examples):

    using System.Data.Objects;
    using System.Linq;

    namespace OverloadTest
    {
        public class Test
        {
            public int Id { get; set; }
        }

        class Program
        {
            static void Main(string[] args)
            {
                IQueryable<Test> queryable = null;
                ObjectQuery<Test> objectQuery = null;

                var query1 = queryable.Where(t => t.Name == "XYZ");
                // no definition for "Name" in class OverloadTest.Text

                var query2 = queryable.Where(t => bla == blabla);
                // "bla", "blabla" do not exist in current context

                var query3 = objectQuery.Where(t => t.Name == "XYZ");
                // Delegate System.Func<Overload.Test,int,bool>
                // does not take 1 argument

                var query4 = objectQuery.Where(t => bla == blabla);
                // Delegate System.Func<Overload.Test,int,bool> 
                // does not take 1 argument
            }
        }
    }

"Squiggles" look different as well in the compiler:

![enter image description here][1]

I understand the first two errors. But why does the compiler apparently want to use the overload number 4 (with the `Func<T, int, bool> predicate`) in the last two examples and doesn't tell me that "Name" isn't defined in class `Test` and that "bla" and "blabla" do not exist in the current context?

I had expected that the compiler can safely rule out overload number 5 (I don't pass in a `string` as parameter) and overload number 2 and 4 (I don't pass in a lambda expression with *two* parameters `(t,i) => ...`) but my expectation doesn't seem to be correct.

As a side note: I came across this problem when looking at [this question][2]. The questioner said there that the fourth query in the question does not compile (it has exactly the compiler error in example number 3 and 4 above), but this query is exactly the solution to his problem and to me it seems that something (a variable or property name?) is written wrong in the query (he didn't confirm this though) but this compiler error doesn't give a helpful indication what is wrong.


  [1]: http://i.stack.imgur.com/CCsep.png
  [2]: http://stackoverflow.com/questions/11729384/returning-a-collection-of-objects-where-an-objects-property-matches-any-property