Consider the following code:
using System;
using System.Linq;
using System.Collections.Generic;
public static class Ex
{
public static IEnumerable<T> Take<T>(this IEnumerable<T> source, long cnt)
{
return source;
}
}
public class C
{
public static void Main()
{
foreach(var e in Enumerable.Range(0, 10).Take(5).ToArray())
Console.Write(e + " ");
}
}
I have an extension on IEnumerable<T>
for Take(long)
, which isn't provided by the framework. The framework only provides Take(int)
. And since I'm calling it with an int
parameter (Take(5)
), I would have expected it to use the framework version, but it's calling my extension.
Am I missing something? The closest match would obviously be the one that takes int
as a parameter, and System.Linq
is included so it should be in the pool of valid overloads. In fact if I delete my extension, the correct framework function is called.
Edit: Moving them to different namespaces shows the same problem:
using System;
using System.Linq;
using System.Collections.Generic;
namespace N1
{
public static class Ex
{
public static IEnumerable<T> Take<T>(this IEnumerable<T> source, long cnt)
{
return source;
}
}
}
namespace N2
{
using N1;
public class C
{
public static void Main()
{
foreach(var e in Enumerable.Range(0, 10).Take(5).ToArray())
Console.Write(e + " ");
}
}
}
Because as Eric Lippert puts it:
the fundamental rule by which one potential overload is judged to be better than another for a given call site: closer is always better than farther away.