views:

44

answers:

2

Hi everyone,

Just for testing reasons, I defined my own Where-Method for Linq like so:

namespace Test
{
    public static class LinqTest
    {
        public static IEnumerable<TSource> Where<TSource>(
                        this IEnumerable<TSource> source,
                        Func<TSource, bool> predicate)
        {
            return new List<TSource> { };
        }
    }
}

So if I use a query like this, I never get a result:

    var test = new string[]{ "a", "b", "c" };
    var x = from y in test
            where y.Length > 0
            select y;
    foreach (var element in x)
        Console.WriteLine(element);

My question is: How does the compiler know which extension method is supposed to be called? The one included in LINQ, or the user-defined one?

Cheers, Chris

+3  A: 

The rules for extension method are similar to those for normal method call lookup. The short version is the compiler will find all of the methods and extension methods which of the name which are accessible and choose the best match among those (with non-extension methods being preferred over extension methods).

Just like normal methods though the choice of which extension method to use can be ambiguous. This would be the case here if both System.Linq and Test namespaces were used within the application. Based on your information it sounds like the test namespace is not referenced with a using hence it won't be considered and the Linq version wins out.

Note: The above is a summary of how lookup occurs and is by no means definitive. The C# language spec is the authority here and covers it in much greater detail.

JaredPar
Thanks, I just tested this in my small example: If everything is in the same namespace the user-defined version wins. If not, the LINQ-Version wins.
Christopher
@Christopher also if you put it into a separate namespace and `using` both `System.Linq` and `Test` then it will error out.
JaredPar
+1  A: 

Normally if you declare conflicting extensions, you will get a compiler error when you try to use it. However, apparently if the extension is defined in the same namespace, it takes precedence without giving an error or even a warning.

Guffa
Seems like you are exactly right, if I put the LinqTest class in another namespace and reference it with a using statement, I get the error "The call is ambiguous between the following methods..."
Christopher